home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 1.iso / desktop / gv21.zip / FILE.C next >
C/C++ Source or Header  |  1995-03-28  |  77KB  |  2,885 lines

  1. /* 'FILE.C' DLL for Graphics Viewer
  2.    Written by: Joe C. Oliphant
  3.    CompuServe 71742, 1451
  4.    E-Mail joe_oliphant@csufresno.edu
  5. */
  6.  
  7. #include "windows.h"
  8. #include "stdio.h"
  9. #include "io.h"
  10. #include "stdlib.h"
  11. #include "string.h"
  12. #include "malloc.h"
  13.  
  14. #define NO_OPEN   -1
  15. #define MEM_ERR   -2
  16. #define BAD_READ  -3
  17. #define BAD_COPY  -4
  18. #define NO_BHND   -5
  19. #define NO_GPTR   -6
  20. #define BAD_CODE  -7
  21. #define BAD_FIRST -8
  22. #define BAD_BIT   -9
  23. #define BAD_HEAD  -10
  24. #define NO_BMP    -11
  25. #define NO_PAL    -12
  26.  
  27. #define pixels2bytes(n) ((n + 7) / 8)
  28.  
  29.  
  30. BITMAPINFOHEADER bmp;
  31. typedef struct {
  32.     unsigned char id[2];
  33.     long          filesize;
  34.     int           reserved[2];
  35.     long          headersize;
  36. } BMPHEAD;
  37. BMPHEAD bmh;
  38.  
  39. typedef struct {
  40.     BITMAPINFOHEADER bmiHeader;
  41.     RGBQUAD          bmiColors[256];
  42. } SBITMAPINFO;
  43. SBITMAPINFO bmpi;
  44.  
  45. typedef struct QCOLOR {
  46.     unsigned char RGB[3];
  47.     unsigned char newcolorindex;
  48.     unsigned long count;
  49.     struct        QCOLOR far *pnext;
  50. } QCOLOR;
  51.  
  52. typedef struct {
  53.     unsigned char RGBmin[3], RGBwidth[3];
  54.     unsigned int  numentries;
  55.     unsigned long count;
  56.     QCOLOR        far *quantizedcolors;
  57. } NEWCOLOR;
  58.  
  59. typedef struct {
  60.     unsigned char sig[6];
  61.     unsigned int  screenwidth, screenheight;
  62.     unsigned char flags, background, aspect;
  63. } GIFHEAD;
  64. GIFHEAD gif;
  65.  
  66. typedef struct {
  67.     unsigned int  left, top, width, height;
  68.     unsigned char flags;
  69. } IMAGEBLOCK;
  70. IMAGEBLOCK iblk;
  71.  
  72. typedef struct {
  73.     unsigned int  w,h;
  74.     unsigned int  x,y;
  75.     unsigned char nPlanes;
  76.     unsigned char masking;
  77.     unsigned char compression;
  78.     unsigned char pad1;
  79.     unsigned int  transparentColor;
  80.     unsigned char xAspect,yAspect;
  81.     unsigned int  pageW,pageH;
  82. } IFFHEAD;
  83. IFFHEAD iff;
  84.  
  85. typedef struct {
  86.     unsigned char key[3];
  87.     unsigned char flag;
  88.     unsigned char pad1;
  89.     unsigned char bits;
  90.     unsigned char pad2[2];
  91.     unsigned char name[4];
  92.     unsigned int  width, height;
  93. } IMGHEAD;
  94. IMGHEAD img;
  95.  
  96. typedef struct {
  97.     unsigned char zerobyte;
  98.     unsigned char name[64];
  99.     unsigned char type[4];
  100. } MACHEAD;
  101. MACHEAD mac;
  102.  
  103. typedef struct {
  104.     unsigned int key1, key2;
  105.     unsigned int width, height;
  106. } MSPHEAD;
  107. MSPHEAD msp;
  108.  
  109. typedef struct {
  110.     unsigned char manufacturer;
  111.     unsigned char version;
  112.     unsigned char encoding;
  113.     unsigned char bits;
  114.     unsigned int  xmin, ymin;
  115.     unsigned int  xmax, ymax;
  116.     unsigned int  hres;
  117.     unsigned int  vres;
  118.     unsigned char palette[48];
  119.     unsigned char reserved;
  120.     unsigned char color_planes;
  121.     unsigned int  bytes_per_line;
  122.     unsigned int  palette_type;
  123.     unsigned char filler[58];
  124. } PCXHEAD;
  125. PCXHEAD pcx;
  126.  
  127. typedef struct {
  128.     unsigned int  mark;
  129.     unsigned int  xsize, ysize;
  130.     unsigned int  xoff, yoff;
  131.     unsigned char bitsinf;
  132.     unsigned char emark;
  133.     unsigned char evideo;
  134.     unsigned int  edesc;
  135.     unsigned int  esize;
  136. } PICHEAD;
  137. PICHEAD pic;
  138.  
  139. typedef struct {
  140.     unsigned int  pbsize;
  141.     unsigned int  bsize;
  142.     unsigned char mbyte;
  143. } PICBLOCK;
  144. PICBLOCK pbk;
  145.  
  146. typedef struct {
  147.     unsigned char identsize;
  148.     unsigned char colormaptype;
  149.     unsigned char imagetype;
  150.     unsigned int  colormapstart;
  151.     unsigned int  colormaplength;
  152.     unsigned char colormapbits;
  153.     unsigned int  xstart;
  154.     unsigned int  ystart;
  155.     unsigned int  width, depth;
  156.     unsigned char bits;
  157.     unsigned char descriptor;
  158. } TGAHEAD;
  159. TGAHEAD tga;
  160.  
  161. typedef struct {
  162.     unsigned char id[4];
  163.     unsigned long start;
  164.     unsigned char product;
  165.     unsigned char filetype;
  166.     unsigned char majorversion;
  167.     unsigned char minorversion;
  168.     unsigned int  encrypt;
  169.     unsigned int  reserved;
  170. } WPGHEAD;
  171. WPGHEAD wpg;
  172.  
  173.  
  174. static char      picbits;
  175. static int       linewidth;
  176. static int       sortRGBaxis;
  177. unsigned char    path[81];
  178. unsigned char    palette[768];
  179. unsigned char    tmppalette[768];
  180. unsigned char    masktable[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  181. unsigned char    bittable[8]  = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  182. unsigned char    buf[255];
  183. GLOBALHANDLE     ghnd;
  184. GLOBALHANDLE     dh;
  185.  
  186.  
  187. int           SetLine(void);
  188. int           Display(unsigned char huge  *gptr, HDC pichdc, HWND pichwnd, int dither,
  189.                       int print, int x, int y, int scale);
  190. int           Quantize(unsigned char huge  *gptr, int far *colorcount,
  191.                        char *outputcolormap);
  192. int           DivideMap(NEWCOLOR far *newcolorsubdiv, int colormapsize,
  193.                         int far *newcolormapsize, char huge *lpstr);
  194. void          psort(char far * far *array, int number);
  195. void          pinsert(char far * far *array, int number);
  196. int           DitherPicture(unsigned char huge *gptr);
  197. long          motr2intellng(long ml, int tf);
  198. int           motr2intelint(int ml, int tf);
  199. unsigned int  GetMIw(FILE *fp, int tf);
  200. unsigned long GetMIlng(FILE *fp, int tf);
  201.  
  202.  
  203. int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine) {
  204.  
  205.        if(wHeapSize > 0)
  206.            UnlockData(0);
  207.        return(1);
  208. }
  209.  
  210.  
  211. HBITMAP FAR PASCAL ReadART(LPSTR fname, HDC pichdc, HWND pichwnd,
  212.                            WORD print, WORD x, WORD y, WORD scale) {
  213.  
  214.     FILE      *fp;
  215.     int       j;
  216.     char      *line;
  217.     long      bufsize;
  218.     unsigned char huge *gptr;
  219.  
  220.     lstrcpy(path, fname);
  221.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  222.     if(getw(fp) != 0) return(BAD_HEAD);
  223.  
  224.     bmp.biWidth = getw(fp);
  225.     getw(fp);
  226.     bmp.biHeight = getw(fp);
  227.     bmp.biBitCount = picbits = 1;
  228.     linewidth = SetLine();
  229.  
  230.     memset(palette, 0, 768);
  231.     memcpy(palette, "\000\000\000\377\377\377", 6);
  232.  
  233.     if((line = malloc(linewidth)) == NULL) {
  234.         fclose(fp);
  235.         return(MEM_ERR);
  236.     }
  237.     bufsize = linewidth * bmp.biHeight;
  238.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  239.         fclose(fp);
  240.         free(line);
  241.         return(MEM_ERR);
  242.     }
  243.     if((gptr = GlobalLock(ghnd)) == NULL) {
  244.         fclose(fp);
  245.         free(line);
  246.         GlobalFree(ghnd);
  247.         return(NO_GPTR);
  248.     }
  249.  
  250.     for (j = 0; j < bmp.biHeight; ++j) {
  251.         fread(line, 1, linewidth, fp);
  252.         if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  253.             GlobalUnlock(ghnd);
  254.                GlobalFree(ghnd);
  255.                free(line);
  256.             fclose(fp);
  257.             return(BAD_COPY);
  258.         }
  259.     }
  260.  
  261.     free(line);
  262.     fclose(fp);
  263.     return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
  264. }
  265.  
  266.  
  267. HBITMAP FAR PASCAL ReadBMP(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  268.                            WORD print, WORD x, WORD y, WORD scale) {
  269.  
  270.     FILE         *fp;
  271.     unsigned int c, d, e, f, h, hf, j, l, n;
  272.     long         compress, bufsize;
  273.     char         *line;
  274.     char huge    *gptr;
  275.  
  276.     lstrcpy(path, fname);
  277.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  278.     if(fread((char *)&bmh,1,sizeof(BMPHEAD),fp) != sizeof(BMPHEAD) ||
  279.         _fmemcmp(bmh.id, "BM", 2)) {
  280.         fclose(fp);
  281.         return(BAD_HEAD);
  282.     }
  283.     if(fread((char *)&bmp,1,sizeof(BITMAPINFOHEADER),fp) != sizeof(BITMAPINFOHEADER)) {
  284.         fclose(fp);
  285.         return(BAD_HEAD);
  286.     }
  287.     if(bmp.biSize != 12) compress = bmp.biCompression;
  288.  
  289.     linewidth = SetLine();
  290.  
  291.     if(bmp.biSize == 12) fseek(fp, 26, SEEK_SET);
  292.     memset(palette, 0, 768);
  293.     if(bmp.biBitCount == 1) memcpy(palette, "\000\000\000\377\377\377", 6);
  294.     if(bmp.biBitCount == 4 || bmp.biBitCount == 8) {
  295.         n = 1 << bmp.biBitCount;
  296.         for(j = 0; j < n; ++j) {
  297.             palette[j * 3 + 2] = fgetc(fp);
  298.             palette[j * 3 + 1] = fgetc(fp);
  299.             palette[j * 3] = fgetc(fp);
  300.             if(bmp.biSize != 12) fgetc(fp);
  301.         }
  302.     }
  303.  
  304.     if((line = malloc(linewidth)) == NULL) {
  305.         fclose(fp);
  306.         return(MEM_ERR);
  307.     }
  308.  
  309.     bufsize = linewidth * bmp.biHeight;
  310.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  311.         fclose(fp);
  312.         free(line);
  313.         return(MEM_ERR);
  314.     }
  315.     if((gptr = GlobalLock(ghnd)) == NULL) {
  316.         fclose(fp);
  317.         free(line);
  318.         GlobalFree(ghnd);
  319.         return(NO_GPTR);
  320.     }
  321.  
  322.     fseek(fp, bmh.headersize, SEEK_SET);
  323.     for(j = bmp.biHeight - 1; j != -1; j--) {
  324.         if(compress == BI_RGB)
  325.             fread(line, 1, linewidth, fp);
  326.         if(compress == BI_RLE4) {
  327.              n = 0;
  328.              hf = FALSE;
  329.              memset(line, 0, linewidth);
  330.              do {
  331.                  c = fgetc(fp);
  332.                  d = fgetc(fp);
  333.                  if(c == 0) {
  334.                      if(d == 0 || d == 1) break;
  335.                      if(d > 2) {
  336.                          e = (d >> 1);
  337.                          while(e--) {
  338.                              f = fgetc(fp);
  339.                              h = f & 0xf0;
  340.                              l = f & 0x0f;
  341.                              if(hf) {
  342.                                  line[n++] |= (h >> 4);
  343.                                  line[n] = (l << 4);
  344.                              }
  345.                              else line[n++] = f;
  346.                          }
  347.                          if(d & 0x01) {
  348.                              if(hf) {
  349.                                  line[n++] |= (h >> 4);
  350.                                  hf = FALSE;
  351.                              }
  352.                              else {
  353.                                  line[n] = h;
  354.                                  hf = TRUE;
  355.                              }
  356.                          }
  357.                          if(ftell(fp) & 1) fgetc(fp);
  358.                      }
  359.                  }
  360.                 else {
  361.                     e = (c >> 1);
  362.                     h = d & 0xf0;
  363.                      l = d & 0x0f;
  364.                     while(e--) {
  365.                          if(hf) {
  366.                              line[n++] |= (h >> 4);
  367.                              line[n] = (l <<4);
  368.                          }
  369.                          else line[n++] = d;
  370.                      }
  371.  
  372.                      if(c & 0x01) {
  373.                          if(hf) {
  374.                              line[n++] |= (h >> 4);
  375.                              hf = FALSE;
  376.                          }
  377.                          else {
  378.                              line[n] = h;
  379.                              hf = TRUE;
  380.                          }
  381.                      }
  382.                 }
  383.             } while(1);
  384.         }
  385.         if(compress == BI_RLE8) {
  386.              n = 0;
  387.              do {
  388.                  c = fgetc(fp);
  389.                  d = fgetc(fp);
  390.                  if(c == 0) {
  391.                      if(d == 0 || d == 1) break;
  392.                      if(d > 2) {
  393.                          while(d--) line[n++] = fgetc(fp);
  394.                          if(ftell(fp) & 1) fgetc(fp);
  395.                      }
  396.                  }
  397.                 else
  398.                     while(c--) line[n++] = d;
  399.             } while(1);
  400.         }
  401.  
  402.         if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  403.             GlobalUnlock(ghnd);
  404.             GlobalFree(ghnd);
  405.             free(line);
  406.             fclose(fp);
  407.             return(BAD_COPY);
  408.         }
  409.     }
  410.     free(line);
  411.     fclose(fp);
  412.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  413. }
  414.  
  415.  
  416. HBITMAP FAR PASCAL ReadCUT(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  417.                            WORD print, WORD x, WORD y, WORD scale) {
  418.  
  419.     FILE       *fp, *fpp;
  420.     int        c, d, i, j, k, l, n = 0;
  421.     char       *line;
  422.     long       bufsize, os;
  423.     char huge  *gptr;
  424.     char       *ptrpath;
  425.  
  426.     lstrcpy(path, fname);
  427.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  428.  
  429.     bmp.biWidth = getw(fp);
  430.     bmp.biHeight = getw(fp);
  431.     bmp.biBitCount = picbits = 8;
  432.     linewidth = SetLine();
  433.  
  434.     memset(palette, 0, 768);
  435.     ptrpath = path;
  436.     while(*ptrpath) {
  437.          if(*ptrpath == '.') {
  438.              _fmemcpy(++ptrpath, "pal", 3);
  439.              break;
  440.          }  else ptrpath++;
  441.     }
  442.  
  443.     if((fpp = fopen(path, "rb")) != NULL) {
  444.         fseek(fpp, 40, SEEK_SET);
  445.         c = 472;
  446.         for(i = 0; i < 256; ++i) {
  447.             for(j = 0; j < 3; ++j)
  448.                 palette[n++] = getw(fpp) & 0xff;
  449.             c -= 6;
  450.             if(c < 6) {
  451.                 fseek(fpp, ftell(fpp) + c, SEEK_SET);
  452.                 c = 512;
  453.             }
  454.         }
  455.            fclose(fpp);
  456.     } else memcpy(palette, "\000\000\000\377\377\377", 6);
  457.  
  458.     if((line = malloc(linewidth)) == NULL) {
  459.         fclose(fp);
  460.         return(MEM_ERR);
  461.     }
  462.  
  463.     bufsize = linewidth * bmp.biHeight;
  464.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  465.         fclose(fp);
  466.         free(line);
  467.         return(MEM_ERR);
  468.     }
  469.     if((gptr = GlobalLock(ghnd)) == NULL) {
  470.         fclose(fp);
  471.         free(line);
  472.         GlobalFree(ghnd);
  473.         return(NO_GPTR);
  474.     }
  475.     fseek(fp, 6, SEEK_SET);
  476.     for(j = 0; j < bmp.biHeight; ++j) {
  477.         n = 0;
  478.         i = getw(fp);
  479.         os = ftell(fp);
  480.         do {
  481.             k = fgetc(fp);
  482.             if(k & 0x80) {
  483.                 l = k & 0x7f;
  484.                 d = fgetc(fp);
  485.                 while(l--) line[n++] = d;
  486.             }
  487.                else {
  488.                    l = k;
  489.                    while(l--) line[n++] = fgetc(fp);
  490.                }
  491.         } while(k != 0 && n < linewidth);
  492.         fseek(fp, os + i, SEEK_SET);
  493.            if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  494.             GlobalUnlock(ghnd);
  495.                GlobalFree(ghnd);
  496.                free(line);
  497.             fclose(fp);
  498.             return(BAD_COPY);
  499.         }
  500.     }
  501.  
  502.     free(line);
  503.     fclose(fp);
  504.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  505. }
  506.  
  507.  
  508. HBITMAP FAR PASCAL ReadGIF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  509.                            WORD print, WORD x, WORD y, WORD scale, long os) {
  510.  
  511.     FILE       *fp;
  512.     int        bits;
  513.     int        bits2;             /* Bits plus 1 */
  514.     int        codesize;       /* Current code size in bits */
  515.     int        codesize2;      /* Next codesize */
  516.     int        nextcode;       /* Next available table entry */
  517.     int        thiscode;       /* Code being expanded */
  518.     int        oldtoken;       /* Last symbol decoded */
  519.     int        currentcode;    /* Code just read */
  520.     int        oldcode;        /* Code read before this one */
  521.     int        bitsleft;       /* Number of bits left in *p */
  522.     int        blocksize = 0;  /* Bytes in next block */
  523.     int        row = 0;           /* next line to write */
  524.     int        byte = 0;       /* next byte to write */
  525.     int        pass = 0;       /* pass number for interlaced pictures */
  526.     int        u;              /* Stack index into firstcodestack */
  527.     int        p = 0;          /* Pointer into current block */
  528.     int        b, c, i, j, n;
  529.     char       *line;
  530.  
  531.        static int firstcodestack[4096];  /* Stack for first codes */
  532.     static int lastcodestack[4096];   /* Statck for previous code */
  533.     static int codestack[4096];       /* Stack for links */
  534.  
  535.     static int wordmasktable[] = {0x0000,0x0001,0x0003,0x0007,
  536.                                   0x000f,0x001f,0x003f,0x007f,
  537.                                   0x00ff,0x01ff,0x03ff,0x07ff,
  538.                                   0x0fff,0x1fff,0x3fff,0x7fff};
  539.  
  540.     static int inctable[]  = { 8,8,4,2,0 }; /* interlace increments */
  541.     static int startable[] = { 0,4,2,1,0 };  /* interlace starts */
  542.     long       bufsize;
  543.     char huge  *gptr;
  544.  
  545.     lstrcpy(path, fname);
  546.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  547.     if(fread((char *)&gif,1,sizeof(GIFHEAD),fp) != sizeof(GIFHEAD) ||
  548.         _fmemcmp(gif.sig, "GIF", 3)) {
  549.         fclose(fp);
  550.         return(BAD_HEAD);
  551.     }
  552.  
  553.     bmp.biWidth = gif.screenwidth;
  554.     bmp.biHeight = gif.screenheight;
  555.     bmp.biBitCount = 8;
  556.     picbits = (gif.flags & 0x0007) + 1;
  557.     linewidth = SetLine();
  558.  
  559.     memset(palette, 0, 768);
  560.     if(gif.flags & 0x80) {
  561.         c = 3 * (1 << ((gif.flags & 7) + 1));
  562.         if(fread(palette, 1, c, fp) != c) {
  563.             fclose(fp);
  564.             return(BAD_READ);
  565.         }
  566.     }
  567.  
  568.     while((c = fgetc(fp)) != EOF && (c == ',' || c == '!' || c & 0xff)) {
  569.  
  570.         if (c == ',') {
  571.             if(os != 0) fseek(fp, os, SEEK_SET);
  572.             if(fread(&iblk,1,sizeof(IMAGEBLOCK),fp) != sizeof(IMAGEBLOCK)) {
  573.                 fclose(fp);
  574.                 return(BAD_READ);
  575.             }
  576.             bmp.biWidth = iblk.width;
  577.             bmp.biHeight = iblk.height;
  578.             picbits = (iblk.flags & 0x0007) + 1;
  579.             linewidth = SetLine();
  580.             if(iblk.flags & 0x80) {
  581.                 memset(palette, 0, 768);
  582.                 b = 3 * (1 << ((iblk.flags & 0x0007) + 1));
  583.                 if(fread(palette, 1, b, fp) != b) {
  584.                     fclose(fp);
  585.                     return(BAD_READ);
  586.                 }
  587.             }
  588.  
  589.             if((line = malloc(max(linewidth, (short)bmp.biWidth))) == NULL) {
  590.                 fclose(fp);
  591.                 return (NO_OPEN);
  592.             }
  593.  
  594.             bits = fgetc(fp);
  595.             bitsleft = 8;
  596.             if(bits < 2 || bits > 8) {
  597.                 fclose(fp);
  598.                 free(line);
  599.                 return(BAD_BIT);
  600.             }
  601.  
  602.             bufsize = linewidth * bmp.biHeight;
  603.             if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  604.                 fclose(fp);
  605.                 free(line);
  606.                 return(MEM_ERR);
  607.             }
  608.             if((gptr = GlobalLock(ghnd)) == NULL) {
  609.                 fclose(fp);
  610.                 free(line);
  611.                 GlobalFree(ghnd);
  612.                 return(NO_GPTR);
  613.             }
  614.             bits2 = 1 << bits;
  615.             nextcode = bits2 + 2;
  616.             codesize2 = 1 << (codesize = bits + 1);
  617.             oldcode = oldtoken = -1;
  618.  
  619.             for(;;) {
  620.                 if(bitsleft == 8) {
  621.                     if(++p >= blocksize) {
  622.                         p = 0;
  623.                         blocksize = fgetc(fp);
  624.                         if((blocksize < 1) ||
  625.                             (fread(buf, 1, blocksize, fp) < blocksize)) {
  626.                             GlobalUnlock(ghnd);
  627.                             GlobalFree(ghnd);
  628.                             fclose(fp);
  629.                             free(line);
  630.                             return(BAD_READ);
  631.                         }
  632.                     }
  633.                     bitsleft = 0;
  634.                 }
  635.                 thiscode = buf[p];
  636.                 if((currentcode = (codesize + bitsleft)) <= 8) {
  637.                     buf[p] >>= codesize;
  638.                     bitsleft = currentcode;
  639.                 }
  640.                 else {
  641.                     if(++p >= blocksize) {
  642.                         p = 0;
  643.                         blocksize = fgetc(fp);
  644.                           if((blocksize < 1) ||
  645.                               (fread(buf, 1, blocksize, fp) < blocksize)) {
  646.                               GlobalUnlock(ghnd);
  647.                             GlobalFree(ghnd);
  648.                             free(line);
  649.                             fclose(fp);
  650.                             return(BAD_READ);
  651.                         }
  652.                     }
  653.                     thiscode |= buf[p] << (8 - bitsleft);
  654.                     if(currentcode <= 16) buf[p] >>= (bitsleft = currentcode - 8);
  655.                     else {
  656.                         if(++p >= blocksize) {
  657.                               p = 0;
  658.                               blocksize = fgetc(fp);
  659.                               if ((blocksize < 1) ||
  660.                                   (fread(buf, 1, blocksize, fp) < blocksize)) {
  661.                                   GlobalUnlock(ghnd);
  662.                                 GlobalFree(ghnd);
  663.                                 free(line);
  664.                                 fclose(fp);
  665.                                 return(BAD_READ);
  666.                             }
  667.                         }
  668.                         thiscode |= buf[p] << (16 - bitsleft);
  669.                         buf[p] >>= (bitsleft = currentcode - 16);
  670.                     }
  671.                 }
  672.                 thiscode &= wordmasktable[codesize];
  673.                 currentcode = thiscode;
  674.  
  675.                 if(thiscode == (bits2 + 1)) break;    /* found EOI */
  676.                 if(thiscode > nextcode) {
  677.                     GlobalUnlock(ghnd);
  678.                     GlobalFree(ghnd);
  679.                     free(line);
  680.                     fclose(fp);
  681.                     return(BAD_CODE);
  682.                 }
  683.  
  684.                 if(thiscode == bits2) {
  685.                     nextcode = bits2 + 2;
  686.                     codesize2 = 1 << (codesize = (bits + 1));
  687.                     oldtoken = oldcode = -1;
  688.                     continue;
  689.                 }
  690.                 u = 0;
  691.                 if(thiscode == nextcode) {
  692.                     if(oldcode == -1) {
  693.                         GlobalUnlock(ghnd);
  694.                         GlobalFree(ghnd);
  695.                         free(line);
  696.                         fclose(fp);
  697.                         return(BAD_FIRST);
  698.                     }
  699.                     firstcodestack[u++] = oldtoken;
  700.                     thiscode = oldcode;
  701.                 }
  702.  
  703.                 while(thiscode >= bits2) {
  704.                     firstcodestack[u++] = lastcodestack[thiscode];
  705.                     thiscode = codestack[thiscode];
  706.                 }
  707.                 oldtoken = thiscode;
  708.                 do {
  709.                     line[byte++] = thiscode;
  710.                     if(byte >= bmp.biWidth) {
  711.                         if(_fmemcpy(gptr + (bmp.biHeight - row - 1) * linewidth, line, linewidth) == NULL) {
  712.                             GlobalUnlock(ghnd);
  713.                             GlobalFree(ghnd);
  714.                             free(line);
  715.                             fclose(fp);
  716.                             return(BAD_COPY);
  717.                         }
  718.                         byte = 0;
  719.                         /* check for interlaced image */
  720.                         if(iblk.flags & 0x40) {
  721.                             row += inctable[pass];
  722.                             if(row >= bmp.biHeight)
  723.                                 row = startable[++pass];
  724.                         } else ++row;
  725.                     }
  726.                     if (u <= 0) break;
  727.                     thiscode = firstcodestack[--u];
  728.                 } while(1);
  729.  
  730.                 if(nextcode < 4096 && oldcode != -1) {
  731.                     codestack[nextcode] = oldcode;
  732.                     lastcodestack[nextcode] = oldtoken;
  733.                     if (++nextcode >= codesize2 && codesize < 12)
  734.                         codesize2 = 1 << ++codesize;
  735.                 }
  736.                 oldcode = currentcode;
  737.             }
  738.  
  739.             free(line);
  740.             fclose(fp);
  741.             return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  742.         }
  743.         else if(c == '!') {
  744.             b = fgetc(fp);
  745.             switch(b) {
  746.                 case 0x001:
  747.                     fseek(fp, 13, SEEK_CUR);
  748.                     do {
  749.                         n = 0;
  750.                         if((n = getc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
  751.                     } while(n > 0);
  752.                     break;
  753.  
  754.                 case 0x00f9:
  755.                     fseek(fp, 6, SEEK_CUR);
  756.                     break;
  757.  
  758.                 case 0x00fe:
  759.                     n = 0;
  760.                     do {
  761.                         n = 0;
  762.                         if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
  763.                     } while(n >0);
  764.                     break;
  765.  
  766.                 case 0x00ff:
  767.                     fseek(fp, 12, SEEK_CUR);
  768.                     do {
  769.                         n = 0;
  770.                         if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
  771.                     } while(n >0);
  772.                     break;
  773.  
  774.                 default:
  775.                     do {
  776.                         n = 0;
  777.                         if((n = fgetc(fp)) != EOF) fseek(fp, n, SEEK_CUR);
  778.                     } while(n >0);
  779.                     break;
  780.             }
  781.         }
  782.     }
  783.     fclose(fp);
  784.     return(NO_BMP);
  785. }
  786.  
  787.  
  788. HBITMAP FAR PASCAL ReadHRZ(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  789.                            WORD print, WORD x, WORD y, WORD scale) {
  790.  
  791.     FILE       *fp;
  792.     int        i, j, n;
  793.     char       r, g, b;
  794.     char       *line;
  795.     long       bufsize;
  796.     char huge  *gptr;
  797.  
  798.     lstrcpy(path, fname);
  799.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  800.  
  801.     bmp.biWidth = 256;
  802.     bmp.biHeight = 240;
  803.     bmp.biBitCount = picbits = 24;
  804.     linewidth = SetLine();
  805.     memset(palette, 0, 768);
  806.  
  807.     if((line = malloc(linewidth)) == NULL) {
  808.         fclose(fp);
  809.         return(MEM_ERR);
  810.     }
  811.  
  812.     bufsize = bmp.biHeight * linewidth;
  813.     ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
  814.     if((gptr = GlobalLock(ghnd)) == NULL) {
  815.         free(line);
  816.         fclose(fp);
  817.         return(MEM_ERR);
  818.     }
  819.  
  820.     for(j = 0; j != bmp.biHeight - 1; ++j) {
  821.         n = 0;
  822.         for(i = 0; i < 256; ++i) {
  823.             r = fgetc(fp);
  824.             g = fgetc(fp);
  825.             b = fgetc(fp);
  826.             line[n++] = b << 2;
  827.             line[n++] = g << 2;
  828.             line[n++] = r << 2;
  829.         }
  830.  
  831.         if(ferror(fp)) {
  832.             free(line);
  833.             fclose(fp);
  834.             return(BAD_READ);
  835.         }
  836.         else {
  837.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  838.                 GlobalUnlock(ghnd);
  839.                 GlobalFree(ghnd);
  840.                 free(line);
  841.                 fclose(fp);
  842.                 return(BAD_COPY);
  843.             }
  844.         }
  845.     }
  846.  
  847.     free(line);
  848.     fclose(fp);
  849.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  850. }
  851.  
  852.  
  853. HBITMAP FAR PASCAL ReadIFF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  854.                            WORD print, WORD x, WORD y, WORD scale) {
  855.  
  856.     FILE          *fp;
  857.     int           c, i, j, k, l, n, t;
  858.     unsigned long lng, pos;
  859.     char          *line, *templine;
  860.     char          subtype[4];
  861.     long          bufsize;
  862.     char huge     *gptr;
  863.     int           bytes;
  864.  
  865.     lstrcpy(path,fname);
  866.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  867.     fread(buf, 1, 4, fp);
  868.     if(!memcmp(buf,"FORM",4) &&
  869.        !memcmp(buf,"LIST",4) &&
  870.        !memcmp(buf,"CAT ",4)) {
  871.         fclose(fp);
  872.         return(BAD_HEAD);
  873.     }
  874.     fread(buf, 1, 8, fp);
  875.     _fmemcpy(subtype, buf + 4, 4);
  876.  
  877.     do {
  878.         fread(buf, 1, 4, fp);
  879.         lng = GetMIlng(fp, FALSE);
  880.         if(lng & 1L) ++lng;
  881.  
  882.         pos = ftell(fp);
  883.  
  884.         if(!memcmp(buf, "BMHD", 4)) {
  885.             if(fread((char *)&iff, 1, sizeof(IFFHEAD), fp)
  886.                 != sizeof(IFFHEAD)) return(BAD_HEAD);
  887.             bmp.biWidth = motr2intelint(iff.w, FALSE);
  888.             bmp.biHeight = motr2intelint(iff.h, FALSE);
  889.             bmp.biBitCount = picbits = iff.nPlanes;
  890.  
  891.             linewidth = SetLine();
  892.             if(!_fmemcmp(subtype, "ILBM", 4))
  893.                 bytes = pixels2bytes(bmp.biWidth) * iff.nPlanes;
  894.             else
  895.                 bytes = bmp.biWidth;
  896.         }
  897.  
  898.         if(!memcmp(buf, "CMAP", 4)) {
  899.             memset(palette, 0, 768);
  900.             if(lng <= 768) {
  901.                 if(fread(palette, 1, (short)lng, fp) != lng) return(BAD_READ);
  902.             }
  903.             else {
  904.                 if(fread(palette, 1, 768, fp) != 768) return(BAD_READ);
  905.                 fseek(fp, lng - 768L, SEEK_SET);
  906.             }
  907.         }
  908.  
  909.         if(!memcmp(buf, "BODY", 4)) {
  910.             if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
  911.                 fclose(fp);
  912.                 return(MEM_ERR);
  913.             }
  914.             if((templine = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
  915.                 free(line);
  916.                 fclose(fp);
  917.                 return(MEM_ERR);
  918.             }
  919.             bufsize = linewidth * bmp.biHeight;
  920.             if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  921.                 fclose(fp);
  922.                 free(line);
  923.                 free(templine);
  924.                 return(MEM_ERR);
  925.             }
  926.             if((gptr = GlobalLock(ghnd)) == NULL) {
  927.                 fclose(fp);
  928.                 free(line);
  929.                 free(templine);
  930.                 GlobalFree(ghnd);
  931.                 return(NO_GPTR);
  932.             }
  933.             for(j = 0; j < bmp.biHeight; ++j) {
  934.                 if(iff.compression) {
  935.                     n = 0;
  936.                     do {
  937.                         c = fgetc(fp);
  938.                         if(c & 0x80) {
  939.                             if(c != 0x80) {
  940.                                 i = ((~c) & 0xff) + 2;
  941.                                 c = fgetc(fp);
  942.                                 while(i--) line[n++] = c;
  943.                             }
  944.                         }
  945.                         else {
  946.                             i = c + 1;
  947.                             while(i--) line[n++] = fgetc(fp);
  948.                         }
  949.                     } while(n < bytes);
  950.                 }
  951.                 else
  952.                     fread(line, 1, bytes, fp);
  953.  
  954.                 if(bmp.biBitCount == 4 || bmp.biBitCount == 8) {
  955.                     t = 0;
  956.                     n = bytes / iff.nPlanes;
  957.                     memset(templine, 0, linewidth);
  958.                       if(bmp.biBitCount <= 4) {
  959.                           for(i = 0; i < n; ++i) {
  960.                               for(k = 0; k < 8; k += 2) {
  961.                                   for(l = 0; l < iff.nPlanes; ++l) {
  962.                                       if(line[i + l * n] & masktable[k])
  963.                                           templine[t] |= bittable[l + 4];
  964.                                       if(line[i + l * n] & masktable[k + 1])
  965.                                           templine[t] |= bittable[l];
  966.                                   }
  967.                                   t++;
  968.                               }
  969.                           }
  970.                     }
  971.                     else {
  972.                           for(i = 0; i < n; ++i) {
  973.                               for(k = 0; k < 8; k++) {
  974.                                   for(l = 0; l < iff.nPlanes; ++l)
  975.                                       if(line[i + l * n] & masktable[k])
  976.                                           templine[t] |= bittable[l];
  977.                                   t++;
  978.                               }
  979.                           }
  980.                     }
  981.                     if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
  982.                         GlobalUnlock(ghnd);
  983.                            GlobalFree(ghnd);
  984.                            free(line);
  985.                            free(templine);
  986.                         fclose(fp);
  987.                         return(BAD_COPY);
  988.                     }
  989.                 }
  990.                 else
  991.                     if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  992.                         GlobalUnlock(ghnd);
  993.                            GlobalFree(ghnd);
  994.                            free(line);
  995.                            free(templine);
  996.                         fclose(fp);
  997.                         return(BAD_COPY);
  998.                     }
  999.  
  1000.                }
  1001.  
  1002.             free(line);
  1003.             free(templine);
  1004.             fclose(fp);
  1005.             return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  1006.         }
  1007.         fseek(fp, pos + lng, SEEK_SET);
  1008.     } while(!feof(fp) || memcmp(buf, "BODY", 4));
  1009.     return(NO_BMP);
  1010. }
  1011.  
  1012.  
  1013. HBITMAP FAR PASCAL ReadIMG(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  1014.                            WORD print, WORD x, WORD y, WORD scale) {
  1015.  
  1016.     FILE       *fp;
  1017.     int        c, i, j, k, l, n = 0, p = 1, t;
  1018.     char       *line, *templine;
  1019.     long       bufsize;
  1020.     char huge  *gptr;
  1021.     int        bytes;
  1022.  
  1023.     lstrcpy(path, fname);
  1024.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1025.     if((fread((char *)&img, 1, sizeof(IMGHEAD), fp) != sizeof(IMGHEAD)) ||
  1026.         (memcmp(img.name, "\000U\000U", 4))) {
  1027.         fclose(fp);
  1028.         return(BAD_HEAD);
  1029.     }
  1030.  
  1031.     bmp.biWidth = motr2intelint(img.width, FALSE);
  1032.     bmp.biHeight = motr2intelint(img.height, FALSE);
  1033.     bmp.biBitCount = picbits = img.bits;
  1034.     if(img.flag == 9) bmp.biBitCount = picbits = 24;
  1035.     if(bmp.biBitCount == 24) bytes = bmp.biWidth * 3;
  1036.     else bytes = pixels2bytes(bmp.biWidth) * bmp.biBitCount;
  1037.  
  1038.     linewidth = SetLine();
  1039.  
  1040.     memset(palette, 0, 768);
  1041.     if(bmp.biBitCount <= 8) {
  1042.         if(bmp.biBitCount == 1)
  1043.             memcpy(palette, "\377\377\377\000\000\000", 6);
  1044.         else {
  1045.             n = 255 / ((1 << img.bits) - 1);
  1046.             for(i = 0; i < (1 << img.bits); ++i)
  1047.                   memset(palette + i * 3, i * n, 3);
  1048.         }
  1049.     }
  1050.  
  1051.     if((line = malloc(max((short)bmp.biWidth, linewidth))) == NULL) {
  1052.         fclose(fp);
  1053.         return(MEM_ERR);
  1054.     }
  1055.     if((templine = malloc(max((short)bmp.biWidth, linewidth))) == NULL) {
  1056.         fclose(fp);
  1057.         free(line);
  1058.         return(MEM_ERR);
  1059.     }
  1060.  
  1061.     bufsize = linewidth * bmp.biHeight;
  1062.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  1063.         fclose(fp);
  1064.         free(line);
  1065.         free(templine);
  1066.         return(MEM_ERR);
  1067.     }
  1068.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1069.         fclose(fp);
  1070.         free(line);
  1071.         free(templine);
  1072.         GlobalFree(ghnd);
  1073.         return(NO_GPTR);
  1074.     }
  1075.  
  1076.     fseek(fp, 16, SEEK_SET);
  1077.     if(bmp.biBitCount == 24) {
  1078.         p = getc(fp);
  1079.         p = getc(fp);
  1080.  
  1081.     }
  1082.     for (j = 0; j < bmp.biHeight; ++j) {
  1083.         n = 0;
  1084.         do {
  1085.             c = fgetc(fp);
  1086.             if(c & 0x80) {
  1087.                 if(c == 0x80) {
  1088.                     i = fgetc(fp) * p;
  1089.                     while(i--) {
  1090.                         if(n >= bytes) break;
  1091.                         line[n++] = fgetc(fp);
  1092.                     }
  1093.                 }
  1094.                 else {
  1095.                     i = (c & 0x7f) * p;
  1096.                     while(i--) {
  1097.                         if(n >= bytes) break;
  1098.                         line[n++] = 0xff;
  1099.                     }
  1100.                 }
  1101.             }
  1102.                else {
  1103.                    if(c == 0) {
  1104.                        i = fgetc(fp) * p;
  1105.                        c = fgetc(fp);
  1106.                    }
  1107.                    else {
  1108.                        i = c * p;
  1109.                        c = 0;
  1110.                    }
  1111.                 while(i--) {
  1112.                     if(n >= bytes) break;
  1113.                     line[n++] = c;
  1114.                 }
  1115.             }
  1116.            } while(n < bytes);
  1117.            if(bmp.biBitCount == 1 || bmp.biBitCount == 24)
  1118.                if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  1119.                 GlobalUnlock(ghnd);
  1120.                    GlobalFree(ghnd);
  1121.                    free(line);
  1122.                 fclose(fp);
  1123.                 return(BAD_COPY);
  1124.             }
  1125.            if(bmp.biBitCount > 1 && bmp.biBitCount <= 8) {
  1126.             t = 0;
  1127.             n = bytes / img.bits;
  1128.             memset(templine, 0, linewidth);
  1129.               if(bmp.biBitCount <= 4) {
  1130.                   for(i = 0; i < n; ++i)
  1131.                       for(k = 0; k < 8; k += 2) {
  1132.                           for(l = 0; l < img.bits; ++l) {
  1133.                               if(line[i + l * n] & masktable[k])
  1134.                                   templine[t] |= bittable[l + 4];
  1135.                               if(line[i + l * n] & masktable[k + 1])
  1136.                                   templine[t] |= bittable[l];
  1137.                           }
  1138.                           ++t;
  1139.                       }
  1140.             }
  1141.             else {
  1142.                   for(i = 0; i < n; ++i)
  1143.                       for(k = 0; k < 8; ++k) {
  1144.                           for(l = 0; l < img.bits; ++l)
  1145.                               if(line[i + l * n] & masktable[k])
  1146.                                   templine[t] |= (masktable[l] >> (8 - img.bits));
  1147.                           ++t;
  1148.                       }
  1149.             }
  1150.             for(i = 0; i < linewidth; ++i)
  1151.                 templine[i] = ~templine[i];
  1152.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
  1153.                 GlobalUnlock(ghnd);
  1154.                    GlobalFree(ghnd);
  1155.                    free(line);
  1156.                    free(templine);
  1157.                 fclose(fp);
  1158.                 return(BAD_COPY);
  1159.             }
  1160.         }
  1161.     }
  1162.  
  1163.     free(line);
  1164.     free(templine);
  1165.     fclose(fp);
  1166.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  1167. }
  1168.  
  1169.  
  1170. HBITMAP FAR PASCAL ReadMAC(LPSTR fname, HDC pichdc, HWND pichwnd,
  1171.                            WORD print, WORD x, WORD y, WORD scale) {
  1172.  
  1173.     FILE      *fp;
  1174.     int       c, i, j, k, n;
  1175.     char      *line;
  1176.     long      bufsize;
  1177.     unsigned char huge *gptr;
  1178.  
  1179.     lstrcpy(path, fname);
  1180.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1181.     if(fread((char *)&mac, 1, sizeof(MACHEAD), fp) != sizeof(MACHEAD)) {
  1182.         fclose(fp);
  1183.         return(BAD_HEAD);
  1184.     }
  1185.  
  1186.     bmp.biWidth = 576;
  1187.     bmp.biHeight = 720;
  1188.     bmp.biBitCount = picbits = 1;
  1189.     linewidth = SetLine();
  1190.  
  1191.     memset(palette, 0, 768);
  1192.     memcpy(palette, "\377\377\377\000\000\000", 6);
  1193.  
  1194.     if((line = malloc(72)) == NULL) {
  1195.         fclose(fp);
  1196.         return(MEM_ERR);
  1197.     }
  1198.  
  1199.     bufsize = linewidth * bmp.biHeight;
  1200.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  1201.         fclose(fp);
  1202.         free(line);
  1203.         return(MEM_ERR);
  1204.     }
  1205.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1206.         fclose(fp);
  1207.         free(line);
  1208.         GlobalFree(ghnd);
  1209.         return(NO_GPTR);
  1210.     }
  1211.     if(!memcmp(mac.type, "PNTG", 4)) fseek(fp, 640, SEEK_SET);
  1212.     else if(mac.zerobyte == 0) fseek(fp, 512, SEEK_SET);
  1213.     else fseek(fp, 0, SEEK_SET);
  1214.     for (j = 0; j < bmp.biHeight; ++j) {
  1215.         n = 0;
  1216.         do {
  1217.             c = fgetc(fp);
  1218.             if(c & 0x80) {
  1219.                 if(c != 0x80) {
  1220.                     i = ((~c) & 0xff) + 2;
  1221.                     c = fgetc(fp);
  1222.                     while(i--) {
  1223.                         if(n > 72) break;
  1224.                         line[n++] = c;
  1225.                     }
  1226.                 }
  1227.             }
  1228.                else {
  1229.                 i = c + 1;
  1230.                 while(i--) {
  1231.                     if(n > 72) break;
  1232.                     line[n++] = fgetc(fp);
  1233.                 }
  1234.             }
  1235.            } while(n < 72);
  1236.         if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, 72) == NULL) {
  1237.             GlobalUnlock(ghnd);
  1238.                GlobalFree(ghnd);
  1239.                free(line);
  1240.             fclose(fp);
  1241.             return(BAD_COPY);
  1242.         }
  1243.     }
  1244.  
  1245.     free(line);
  1246.     fclose(fp);
  1247.     return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
  1248. }
  1249.  
  1250.  
  1251. HBITMAP FAR PASCAL ReadMSP(LPSTR fname, HDC pichdc, HWND pichwnd,
  1252.                            WORD print, WORD x, WORD y, WORD scale) {
  1253.  
  1254.     FILE      *fp;
  1255.     int       c, i, j, k, n;
  1256.     char      *line;
  1257.     long      bufsize;
  1258.     unsigned char huge *gptr;
  1259.     int       bytes;
  1260.  
  1261.     lstrcpy(path, fname);
  1262.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1263.     if(fread((char *)&msp, 1, sizeof(MSPHEAD), fp) != sizeof(MSPHEAD)) {
  1264.         fclose(fp);
  1265.         return(BAD_HEAD);
  1266.     }
  1267.     if((msp.key1 == 0x6144 || msp.key1 == 0x694c) &&
  1268.        (msp.key2 == 0x4d6e || msp.key2 == 0x536e)) {
  1269.         bmp.biWidth = msp.width;
  1270.         bmp.biHeight = msp.height;
  1271.         bmp.biBitCount = picbits = 1;
  1272.         bytes = pixels2bytes(msp.width);
  1273.         linewidth = SetLine();
  1274.     }
  1275.     else {
  1276.         fclose(fp);
  1277.         return(BAD_HEAD);
  1278.     }
  1279.  
  1280.     memset(palette, 0, 768);
  1281.     memcpy(palette, "\000\000\000\377\377\377", 6);
  1282.  
  1283.     if((line = malloc(max(bytes, linewidth))) == NULL) {
  1284.         fclose(fp);
  1285.         return(MEM_ERR);
  1286.     }
  1287.     bufsize = linewidth * bmp.biHeight;
  1288.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  1289.         fclose(fp);
  1290.         free(line);
  1291.         return(MEM_ERR);
  1292.     }
  1293.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1294.         fclose(fp);
  1295.         free(line);
  1296.         GlobalFree(ghnd);
  1297.         return(NO_GPTR);
  1298.     }
  1299.     fseek(fp, bmp.biHeight * 2 + 32, SEEK_SET);
  1300.     for (j = 0; j < bmp.biHeight; ++j) {
  1301.         n = 0;
  1302.         do {
  1303.             c = fgetc(fp);
  1304.             if(!c) {
  1305.                 k = fgetc(fp) & 0x00ff;
  1306.                 c = fgetc(fp);
  1307.                 for(i=0; i<k; ++i) line[n++] = c;
  1308.             }
  1309.             else {
  1310.                 for(i=0; i<c; ++i) line[n++] = fgetc(fp);
  1311.             }
  1312.         } while(n < bytes);
  1313.         if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  1314.             GlobalUnlock(ghnd);
  1315.                GlobalFree(ghnd);
  1316.                free(line);
  1317.             fclose(fp);
  1318.             return(BAD_COPY);
  1319.         }
  1320.     }
  1321.  
  1322.     free(line);
  1323.     fclose(fp);
  1324.     return(Display(gptr, pichdc, pichwnd, 0, print, x, y, scale));
  1325. }
  1326.  
  1327.  
  1328. HBITMAP FAR PASCAL ReadPCX(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  1329.                            WORD print, WORD x, WORD y, WORD scale) {
  1330.  
  1331.     FILE       *fp;
  1332.     int        c, i, j, k, l, n, t;
  1333.     char       *line, *templine;
  1334.     long       bufsize;
  1335.     char huge  *gptr;
  1336.     int        bytes;
  1337.     char       *pal;
  1338.     static char pcxpalette[48] = {0x00, 0x00, 0x0E, 0x00, 0x52, 0x07, 0x2C, 0x00,
  1339.                                   0x0E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x2C, 0x00,
  1340.                                   0x85, 0x0F, 0x42, 0x00, 0x00, 0x21, 0x00, 0x00,
  1341.                                   0x00, 0x00, 0x6A, 0x24, 0x9B, 0x49, 0xA1, 0x5E,
  1342.                                   0x90, 0x5E, 0x18, 0x5E, 0x84, 0x14, 0xD9, 0x95,
  1343.                                   0xA0, 0x14, 0x12, 0x00, 0x06, 0x00, 0x68, 0x1F};
  1344.  
  1345.     lstrcpy(path,fname);
  1346.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1347.     if((fread((char *)&pcx, 1, sizeof(PCXHEAD), fp) != sizeof(PCXHEAD))  ||
  1348.        pcx.manufacturer != 0x0a) {
  1349.         fclose(fp);
  1350.         return(BAD_HEAD);
  1351.     }
  1352.  
  1353.     bmp.biWidth = pcx.xmax - pcx.xmin + 1;
  1354.     bmp.biHeight = pcx.ymax - pcx.ymin + 1;
  1355.     bytes = pcx.bytes_per_line * pcx.color_planes;
  1356.     bmp.biBitCount = picbits = pcx.bits * pcx.color_planes;
  1357.     linewidth = SetLine();
  1358.  
  1359.     memset(palette, 0, 768);
  1360.     if(bmp.biBitCount <= 8) {
  1361.         if(bmp.biBitCount == 1) memcpy(palette, "\000\000\000\377\377\377", 6);
  1362.         if(bmp.biBitCount == 4) memcpy(palette, pcx.palette, 48);
  1363.         if(pcx.version == 3) memcpy(palette, pcxpalette, 48);
  1364.         if(bmp.biBitCount == 8 && pcx.version >= 5) {
  1365.             fseek(fp, -769L, SEEK_END);
  1366.             if(fgetc(fp) == 12) {
  1367.                 if(fread(palette, 1, 768, fp) != 768) {
  1368.                     fclose(fp);
  1369.                     return(BAD_READ);
  1370.                 }
  1371.             }
  1372.         }
  1373.     }
  1374.  
  1375.     if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
  1376.         fclose(fp);
  1377.         return(MEM_ERR);
  1378.     }
  1379.     if((templine = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
  1380.         free(line);
  1381.         fclose(fp);
  1382.         return(MEM_ERR);
  1383.     }
  1384.  
  1385.     bufsize = max(bytes, linewidth) * bmp.biHeight;
  1386.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  1387.         fclose(fp);
  1388.         free(line);
  1389.         free(templine);
  1390.         return(MEM_ERR);
  1391.     }
  1392.  
  1393.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1394.         fclose(fp);
  1395.         free(line);
  1396.         free(templine);
  1397.         GlobalFree(ghnd);
  1398.         return(NO_GPTR);
  1399.     }
  1400.     if(bmp.biBitCount == 24) linewidth = max(bytes, linewidth);
  1401.  
  1402.     fseek(fp, 128L, SEEK_SET);
  1403.     for(j = 0; j < bmp.biHeight; ++j) {
  1404.         n = 0;
  1405.         do {
  1406.             c = fgetc(fp);
  1407.             if((c & 0xc0) == 0xc0)  {
  1408.                 i = c & 0x3f;
  1409.                 c = fgetc(fp);
  1410.                 while(i--) {
  1411.                     if(n >= bytes) break;
  1412.                     line[n++]=c;
  1413.                 }
  1414.             }
  1415.             else {
  1416.                   if(n >= bytes) break;
  1417.                 line[n++]=c;
  1418.             }
  1419.         } while(n < bytes);
  1420.  
  1421.         if(pcx.color_planes == 1) {
  1422.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  1423.                 GlobalUnlock(ghnd);
  1424.                    GlobalFree(ghnd);
  1425.                    free(line);
  1426.                    free(templine);
  1427.                 fclose(fp);
  1428.                 return(BAD_COPY);
  1429.             }
  1430.            }
  1431.         if(pcx.color_planes > 1 && pcx.color_planes <= 4) {
  1432.             t = 0;
  1433.               n = bytes / pcx.color_planes;
  1434.               if(bmp.biBitCount == 24) {
  1435.                      for(i = 0; i < n; ++i)
  1436.                       for(k = 2; k > -1; k--) templine[t++] = line[i + n * k];
  1437.               }
  1438.               else {
  1439.                   memset(templine, 0, linewidth);
  1440.                   for(i = 0; i < n; ++i) {
  1441.                       for(k = 0; k < 8; k += 2) {
  1442.                           for(l = 0; l < pcx.color_planes; ++l) {
  1443.                               if(line[i + l * n] & masktable[k])
  1444.                                   templine[t] |= bittable[l + 4];
  1445.                               if(line[i + l * n] & masktable[k + 1])
  1446.                                   templine[t] |= bittable[l];
  1447.                           }
  1448.                           t++;
  1449.                       }
  1450.                   }
  1451.             }
  1452.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, templine, linewidth) == NULL) {
  1453.                 GlobalUnlock(ghnd);
  1454.                    GlobalFree(ghnd);
  1455.                    free(line);
  1456.                    free(templine);
  1457.                 fclose(fp);
  1458.                 return(BAD_COPY);
  1459.             }
  1460.         }
  1461.        }
  1462.  
  1463.     free(line);
  1464.     free(templine);
  1465.     fclose(fp);
  1466.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  1467. }
  1468.  
  1469.  
  1470. HBITMAP FAR PASCAL ReadPIC(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  1471.                            WORD print, WORD x, WORD y, WORD scale) {
  1472.  
  1473.     FILE          *fp;
  1474.     unsigned long l;
  1475.     int           bcount, c, i, j, k, n, ldex = 0, len, t = 0;
  1476.     int           r, b, g;
  1477.     int           row = 0;
  1478.     int           pass, pos;
  1479.     char          *line, *block;
  1480.     char          bits;
  1481.     char          temppal[48];
  1482.     long          bufsize;
  1483.     char huge     *gptr;
  1484.     int           bytes;
  1485.  
  1486.     lstrcpy(path, fname);
  1487.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1488.     if((fread((char *)&pic, 1, sizeof(PICHEAD), fp) != sizeof(PICHEAD))  ||
  1489.         (pic.mark != 0x1234)) {
  1490.         fclose(fp);
  1491.         return(BAD_HEAD);
  1492.     }
  1493.  
  1494.     bmp.biWidth = pic.xsize;
  1495.     bmp.biHeight = pic.ysize;
  1496.     n = (pic.bitsinf & 0xf0) / 16 + 1;
  1497.     bits = picbits = bmp.biBitCount = n * (pic.bitsinf & 0xf);
  1498.     if(bmp.biBitCount == 8) bytes = pic.xsize;
  1499.     else bytes = pixels2bytes(pic.xsize);
  1500.     linewidth = SetLine();
  1501.  
  1502.     memset(palette, 0, 768);
  1503.     fread(palette, 1 , pic.esize, fp);
  1504.     if(bits == 1)
  1505.         memcpy(palette, "\000\000\000\377\377\377", 6);
  1506.     else if(bits > 1 && bits <= 4 && pic.evideo != 'M') {
  1507.         for(i = 0; i < (1 << bits); ++i) {
  1508.             r = g = b = 0;
  1509.             if(palette[i] & 0x01) b += 0x80;
  1510.             if(palette[i] & 0x08) b += 0x40;
  1511.             if(palette[i] & 0x02) g += 0x80;
  1512.             if(palette[i] & 0x10) g += 0x40;
  1513.             if(palette[i] & 0x04) r += 0x80;
  1514.             if(palette[i] & 0x20) r += 0x40;
  1515.             temppal[t++] = r;
  1516.             temppal[t++] = g;
  1517.             temppal[t++] = b;
  1518.         }
  1519.         _fmemcpy(palette, temppal, (1 << bits) * 3);
  1520.     } else
  1521.         for(i = 0; i < pic.esize; ++i)
  1522.             palette[i] <<= 2;
  1523.  
  1524.     if((line = malloc(max((short)bmp.biWidth, bytes))) == NULL) {
  1525.         fclose(fp);
  1526.         return(MEM_ERR);
  1527.     }
  1528.     if((block = malloc(8192)) == NULL) {
  1529.         free(line);
  1530.         fclose(fp);
  1531.         return(MEM_ERR);
  1532.     }
  1533.     bufsize = linewidth * bmp.biHeight;
  1534.     if((ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize)) == NULL) {
  1535.         fclose(fp);
  1536.         free(line);
  1537.         free(block);
  1538.         return(MEM_ERR);
  1539.     }
  1540.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1541.         fclose(fp);
  1542.         free(line);
  1543.         free(block);
  1544.         GlobalFree(ghnd);
  1545.         return(NO_GPTR);
  1546.     }
  1547.  
  1548.     if(bits > 1 && bits <= 4) {
  1549.          _fmemset(gptr, 0, (unsigned)bufsize);
  1550.          row = bmp.biHeight * bits;
  1551.     } else
  1552.            row = bmp.biHeight;
  1553.  
  1554.     bcount = getw(fp);
  1555.     if(bcount) {
  1556.         for(i = 0; i < bcount; ++i) {
  1557.             l = ftell(fp);
  1558.             pos = 0;
  1559.              if(fread((char *)&pbk, 1, sizeof(PICBLOCK), fp) != sizeof(PICBLOCK)) {
  1560.                 GlobalUnlock(ghnd);
  1561.                    GlobalFree(ghnd);
  1562.                 free(line);
  1563.                 free(block);
  1564.                 fclose(fp);
  1565.                 return(BAD_READ);
  1566.             }
  1567.              do {
  1568.                 c = fgetc(fp);
  1569.                 len = 1;
  1570.                 if(c == pbk.mbyte) {
  1571.                     len = fgetc(fp);
  1572.                     if(len == 0) len = getw(fp);
  1573.                     c = fgetc(fp);
  1574.                     memset(block + ldex, c, len);
  1575.                     ldex += len;
  1576.                 } else block[ldex++] = c;
  1577.                 pos += len;
  1578.                 while(ldex >= bytes) {
  1579.                     ldex -= bytes;
  1580.                      if(bmp.biBitCount == 8 || bmp.biBitCount == 1)
  1581.                         if (row > 0)
  1582.                             if(_fmemcpy(gptr + (bmp.biHeight - row) * linewidth, block, bytes) == NULL) {
  1583.                                 GlobalUnlock(ghnd);
  1584.                                    GlobalFree(ghnd);
  1585.                                 free(line);
  1586.                                 free(block);
  1587.                                 fclose(fp);
  1588.                                 return(BAD_COPY);
  1589.                             }
  1590.                     if(bits >1 && bits <= 4) {
  1591.                         if(_fmemcpy(line, gptr + (bmp.biHeight - row % bmp.biHeight - 1) * linewidth, linewidth) == NULL) {
  1592.                             GlobalUnlock(ghnd);
  1593.                                GlobalFree(ghnd);
  1594.                             free(line);
  1595.                             free(block);
  1596.                             fclose(fp);
  1597.                             return(BAD_COPY);
  1598.                         }
  1599.                         pass =  row / bmp.biHeight;
  1600.                         n = 0;
  1601.                         for(j = 0; j < bytes; ++j) {
  1602.                             for(k = 0; k < 8; k += 2) {
  1603.                                 if(block[j] & masktable[k]) line[n] |= bittable[7 - pass];
  1604.                                 if(block[j] & masktable[k + 1]) line[n] |= bittable[3 - pass];
  1605.                                 n++;
  1606.                             }
  1607.                         }
  1608.                         if(_fmemcpy(gptr + (bmp.biHeight - row % bmp.biHeight - 1) * linewidth, line, linewidth) == NULL) {
  1609.                             GlobalUnlock(ghnd);
  1610.                                GlobalFree(ghnd);
  1611.                             free(line);
  1612.                             free(block);
  1613.                             fclose(fp);
  1614.                             return(BAD_COPY);
  1615.                         }
  1616.                     }
  1617.                     --row;
  1618.                     memmove(block, block + bytes, ldex);
  1619.                 }
  1620.             } while(pos < pbk.bsize && c != EOF);
  1621.             fseek(fp, l + (long)pbk.pbsize, SEEK_SET);
  1622.         }
  1623.     }
  1624.     else {
  1625.         GlobalUnlock(ghnd);
  1626.         GlobalFree(ghnd);
  1627.         free(block);
  1628.         free(line);
  1629.         fclose(fp);
  1630.         return(BAD_READ);
  1631.     }
  1632.  
  1633.     free(line);
  1634.     fclose(fp);
  1635.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  1636. }
  1637.  
  1638.  
  1639. HBITMAP FAR PASCAL ReadRAS(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  1640.                            WORD print, WORD x, WORD y, WORD scale) {
  1641.  
  1642.     FILE       *fp;
  1643.     int        c, i, j, n, m;
  1644.     long       bits, typ, mtyp, mapl, pl;
  1645.     char       *line;
  1646.     long       bufsize;
  1647.     char huge  *gptr;
  1648.     int        bytes;
  1649.  
  1650.     lstrcpy(path, fname);
  1651.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1652.  
  1653.  
  1654.     if(GetMIlng(fp, FALSE) != 0x59a66a95) {
  1655.         fclose(fp);
  1656.         return(BAD_HEAD);
  1657.     }
  1658.  
  1659.     bmp.biWidth = GetMIlng(fp, FALSE);
  1660.     bmp.biHeight = GetMIlng(fp, FALSE);
  1661.     bits = bmp.biBitCount = picbits = GetMIlng(fp, FALSE);
  1662.  
  1663.     bytes = linewidth = SetLine();
  1664.  
  1665.     memset(palette, 0, 768);
  1666.     GetMIlng(fp, FALSE);
  1667.     typ = GetMIlng(fp, FALSE);
  1668.     if(typ == 0xffff) {
  1669.         fclose(fp);
  1670.         return(BAD_HEAD);
  1671.     }
  1672.  
  1673.     mtyp = GetMIlng(fp, FALSE);
  1674.     if(mtyp == 0x2) {
  1675.         fclose(fp);
  1676.         return(BAD_HEAD);
  1677.     }
  1678.     mapl = GetMIlng(fp, FALSE);
  1679.     if(bmp.biBitCount == 1) memcpy(palette,"\000\000\000\377\377\377",6);
  1680.     if(mtyp) {
  1681.         fread(tmppalette, 1, (int)mapl, fp);
  1682.         pl = mapl / 3;
  1683.         j = 0;
  1684.         for(i = 0; i < pl; ++i) {
  1685.             if(i >= 256) break;
  1686.             palette[i * 3] = tmppalette[j++];
  1687.             palette[i * 3 + 1] = tmppalette[i + pl];
  1688.             palette[i * 3 + 2] = tmppalette[i + pl * 2];
  1689.         }
  1690.     }
  1691.  
  1692.     if((line = malloc(max(linewidth, bytes))) == NULL) {
  1693.         fclose(fp);
  1694.         return(MEM_ERR);
  1695.     }
  1696.     bufsize = bmp.biHeight * linewidth;
  1697.     ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
  1698.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1699.         free(line);
  1700.         fclose(fp);
  1701.         return(MEM_ERR);
  1702.     }
  1703.  
  1704.     if(bmp.biBitCount == 24) {
  1705.         bytes = bmp.biWidth * 3;
  1706.         while(bytes & 0x0001) ++bytes;
  1707.     }
  1708.  
  1709.     for(j = 0; j != bmp.biHeight - 1; ++j) {
  1710.         n = 0;
  1711.         /* handle uncompressed lines */
  1712.         if(typ != 0x02) {
  1713.             if(bits == 1 || bits == 8 || bits == 24) {
  1714.                 fread(line, 1, bytes, fp);
  1715.                 n = bytes;
  1716.             }
  1717.  
  1718.             if(bits == 32) {
  1719.                 for(i = 0; i < bmp.biWidth; ++i) {
  1720.                     if(n >= bytes - 3) continue;
  1721.                     fgetc(fp);
  1722.                     line[n++] = fgetc(fp);
  1723.                     line[n++] = fgetc(fp);
  1724.                     line[n++] = fgetc(fp);
  1725.                 }
  1726.             }
  1727.         }
  1728.  
  1729.         /* handle compressed lines */
  1730.         else {
  1731.             do {
  1732.                 c = fgetc(fp);
  1733.                 if(c != 0x80) line[n++] = c;
  1734.                 else {
  1735.                     c = fgetc(fp);
  1736.                     if(c == 0) line[n++] = 0x80;
  1737.                     else {
  1738.                         m = fgetc(fp);
  1739.                         for(i = 0; i < c; ++i) if(n <= bytes) line[n++] = m;
  1740.                     }
  1741.                 }
  1742.             } while(n < bytes);
  1743.         }
  1744.         if(ferror(fp)) {
  1745.             free(line);
  1746.             fclose(fp);
  1747.             return(BAD_READ);
  1748.         }
  1749.         else {
  1750.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, linewidth) == NULL) {
  1751.                 GlobalUnlock(ghnd);
  1752.                 GlobalFree(ghnd);
  1753.                 free(line);
  1754.                 fclose(fp);
  1755.                 return(BAD_COPY);
  1756.             }
  1757.         }
  1758.     }
  1759.  
  1760.     free(line);
  1761.     fclose(fp);
  1762.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  1763. }
  1764.  
  1765.  
  1766. HBITMAP FAR PASCAL ReadTGA(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  1767.                            WORD print, WORD x, WORD y, WORD scale) {
  1768.  
  1769.     FILE       *fp;
  1770.     int        c, i, j, n, m, size;
  1771.     int        r, g, b;
  1772.     int        startline, endline, incline;
  1773.     char       *line, *templine;
  1774.     long       bufsize;
  1775.     char huge  *gptr;
  1776.     int        bytes;
  1777.  
  1778.     lstrcpy(path, fname);
  1779.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  1780.  
  1781.     if((fread((char *)&tga, 1, sizeof(TGAHEAD), fp) != sizeof(TGAHEAD)) ||
  1782.         (tga.imagetype != 0x01 &&
  1783.          tga.imagetype != 0x02 &&
  1784.          tga.imagetype != 0x03 &&
  1785.          tga.imagetype != 0x09 &&
  1786.          tga.imagetype != 0x0a &&
  1787.          tga.imagetype != 0x0b)) {
  1788.         fclose(fp);
  1789.         return(BAD_HEAD);
  1790.     }
  1791.  
  1792.     bmp.biWidth = tga.width;
  1793.     bmp.biHeight = tga.depth;
  1794.     bmp.biBitCount = picbits = tga.bits;
  1795.     if(bmp.biBitCount == 1) bytes = pixels2bytes(bmp.biWidth);
  1796.     else if(bmp.biBitCount == 8) bytes = bmp.biWidth;
  1797.     else bytes = bmp.biWidth * 3;
  1798.     linewidth = SetLine();
  1799.  
  1800.     memset(palette, 0, 768);
  1801.     fseek(fp, (long)tga.identsize, SEEK_CUR);
  1802.     if(tga.bits == 1) memcpy(palette,"\000\000\000\377\377\377",6);
  1803.     if(tga.colormaptype) {
  1804.         switch(tga.colormapbits) {
  1805.             case 24:
  1806.                 for(i = tga.colormapstart; i < tga.colormaplength; ++i) {
  1807.                     if(i >= 256) break;
  1808.                     palette[i * 3 + 2] = fgetc(fp);
  1809.                     palette[i * 3 + 1] = fgetc(fp);
  1810.                     palette[i * 3] = fgetc(fp);
  1811.                 }
  1812.                 break;
  1813.             case 16:
  1814.                 for(i = tga.colormapstart; i < tga.colormaplength; ++i) {
  1815.                     if(i >= 256) break;
  1816.                     n = getw(fp);
  1817.                     palette[i * 3 + 2] = ((n >> 10) & 0x1f) << 3;
  1818.                     palette[i * 3 + 1] = ((n >> 5) & 0x1f) << 3;
  1819.                     palette[i * 3] = (n & 0x1f) << 3;
  1820.                 }
  1821.                 break;
  1822.         }
  1823.     }
  1824.     else
  1825.         if(tga.bits == 8)
  1826.             for(i = 0; i < 256; ++i)
  1827.                 memset(palette + i * 3, i, 3);
  1828.  
  1829.  
  1830.     if((line = malloc(max(bytes, linewidth))) == NULL) {
  1831.         fclose(fp);
  1832.         return(MEM_ERR);
  1833.     }
  1834.     bufsize = bmp.biHeight * linewidth;
  1835.     ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
  1836.     if((gptr = GlobalLock(ghnd)) == NULL) {
  1837.         free(line);
  1838.         fclose(fp);
  1839.         return(MEM_ERR);
  1840.     }
  1841.  
  1842.     if(tga.descriptor & 0x20) {
  1843.         startline = 0;
  1844.         endline = bmp.biHeight;
  1845.         incline = 1;
  1846.     }
  1847.     else {
  1848.         startline = bmp.biHeight - 1;
  1849.         endline = -1;
  1850.         incline = -1;
  1851.     }
  1852.  
  1853.     for(j = startline; j != endline; j += incline) {
  1854.         n = m = 0;
  1855.         /* handle uncompressed lines */
  1856.         if(tga.imagetype == 0x01 ||
  1857.            tga.imagetype == 0x02 ||
  1858.            tga.imagetype == 0x03) {
  1859.             if(tga.bits == 1 || tga.bits == 8 || tga.bits == 24) {
  1860.                 fread(line, 1, bytes, fp);
  1861.                 n = bytes;
  1862.             }
  1863.             if(tga.bits == 16) {
  1864.                 for(i = 0; i < bmp.biWidth; ++i) {
  1865.                     c = getw(fp);
  1866.                     if(n >= bytes - 3) continue;
  1867.                     line[n++] = (c & 0x1f) << 3;
  1868.                     line[n++] = ((c >> 5) & 0x1f) << 3;
  1869.                     line[n++] = ((c >> 10) & 0x1f) << 3;
  1870.                 }
  1871.             }
  1872.             if(tga.bits == 32) {
  1873.                 for(i = 0; i < bmp.biWidth; ++i) {
  1874.                     if(n >= bytes - 3) continue;
  1875.                     line[n++] = fgetc(fp);
  1876.                     line[n++] = fgetc(fp);
  1877.                     line[n++] = fgetc(fp);
  1878.                     fgetc(fp);
  1879.                 }
  1880.             }
  1881.         }
  1882.  
  1883.         /* handle compressed lines */
  1884.         else {
  1885.             do {
  1886.                 c = fgetc(fp);
  1887.                 size = (c & 0x7f) + 1;
  1888.                 n += size;
  1889.                 if(c & 0x80) {
  1890.                     switch(tga.bits) {
  1891.                         case 1:
  1892.                         case 8:
  1893.                             c = fgetc(fp);
  1894.                             for(i = 0 ; i < size; ++i) {
  1895.                                 if(m >= bytes) continue;
  1896.                                 line[m++] = c;
  1897.                             }
  1898.                             break;
  1899.                         case 16:
  1900.                             c = getw(fp);
  1901.                             r = ((c >> 10) & 0x1f) << 3;
  1902.                             g = ((c >> 5) & 0x1f) << 3;
  1903.                             b = (c & 0x1f) << 3;
  1904.                             for(i = 0; i < size; ++i) {
  1905.                                 if(m >= bytes - 3) continue;
  1906.                                 line[m++] = b;
  1907.                                 line[m++] = g;
  1908.                                 line[m++] = r;
  1909.                             }
  1910.                             break;
  1911.                         case 24:
  1912.                             b = fgetc(fp);
  1913.                             g = fgetc(fp);
  1914.                             r = fgetc(fp);
  1915.                             for(i = 0; i < size; ++i) {
  1916.                                 if(m >= bytes - 3) continue;
  1917.                                 line[m++] = b;
  1918.                                 line[m++] = g;
  1919.                                 line[m++] = r;
  1920.                             }
  1921.                             break;
  1922.                         case 32:
  1923.                             b = fgetc(fp);
  1924.                             g = fgetc(fp);
  1925.                             r = fgetc(fp);
  1926.                             fgetc(fp);
  1927.                             for(i = 0; i < size; ++i) {
  1928.                                 if(m >= bytes - 3) continue;
  1929.                                 line[m++] = b;
  1930.                                 line[m++] = g;
  1931.                                 line[m++] = r;
  1932.                             }
  1933.                             break;
  1934.                     }
  1935.                 }
  1936.                 else {
  1937.                     switch(tga.bits) {
  1938.                         case 1:
  1939.                         case 8:
  1940.                             for(i = 0; i < size; ++i) {
  1941.                                 if(m >= bytes) continue;
  1942.                                 line[m++] = fgetc(fp);
  1943.                             }
  1944.                             break;
  1945.                         case 16:
  1946.                             for(i = 0; i < size; ++i) {
  1947.                                 c = getw(fp);
  1948.                                 r = ((c >> 10) & 0x1f) << 3;
  1949.                                 g = ((c >> 5) & 0x1f) << 3;
  1950.                                 b = (c & 0x1f) << 3;
  1951.                                 if(m >= bytes - 3) continue;
  1952.                                 line[m++] = b;
  1953.                                 line[m++] = g;
  1954.                                 line[m++] = r;
  1955.                             }
  1956.                             break;
  1957.                         case 24:
  1958.                             for(i = 0; i < size; ++i) {
  1959.                                 if(m >= bytes - 3) continue;
  1960.                                 line[m++] = fgetc(fp);
  1961.                                 line[m++] = fgetc(fp);
  1962.                                 line[m++] = fgetc(fp);
  1963.                             }
  1964.                             break;
  1965.                         case 32:
  1966.                             for(i = 0; i < size; ++i) {
  1967.                                 if(m >= bytes - 3) continue;
  1968.                                 line[m++] = fgetc(fp);
  1969.                                 line[m++] = fgetc(fp);
  1970.                                 line[m++] = fgetc(fp);
  1971.                                 fgetc(fp);
  1972.                             }
  1973.                             break;
  1974.                     }
  1975.                 }
  1976.             } while(n < bytes);
  1977.         }
  1978.         if(ferror(fp)) {
  1979.             free(line);
  1980.             fclose(fp);
  1981.             return(BAD_READ);
  1982.         }
  1983.         else {
  1984.             if(tga.descriptor & 0x10) {
  1985.                 if((templine = malloc(bytes)) != NULL) {
  1986.                     for(i = 0; i < bytes; ++i)
  1987.                         templine[i] = line[bytes - 1 - i];
  1988.                     memcpy(line, templine, bytes);
  1989.                     free(templine);
  1990.                 }
  1991.             }
  1992.             if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, bytes) == NULL) {
  1993.                 GlobalUnlock(ghnd);
  1994.                 GlobalFree(ghnd);
  1995.                 free(line);
  1996.                 fclose(fp);
  1997.                 return(BAD_COPY);
  1998.             }
  1999.         }
  2000.     }
  2001.  
  2002.     free(line);
  2003.     fclose(fp);
  2004.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  2005. }
  2006.  
  2007.  
  2008. HBITMAP FAR PASCAL ReadTIF(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  2009.                            WORD print, WORD x, WORD y, WORD scale) {
  2010.  
  2011.     FILE          *fp;
  2012.     int           c, i, j, k, n, row = 0, t;
  2013.     int           colormap = FALSE, motint = FALSE;
  2014.     char          *line;
  2015.     long          bufsize;
  2016.     unsigned long length, offset, pos, strtstrip;
  2017.     unsigned int  numtags, photo = 0, rows = 0, numstrips = 1, compress = 1;
  2018.     unsigned int  bitsamples = 1, bitspersample = 1, tag, type;
  2019.     char huge     *gptr;
  2020.     int           bytes;
  2021.  
  2022.     lstrcpy(path, fname);
  2023.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  2024.     fread(buf, 1, 2, fp);
  2025.     if(!_fmemcmp(buf, "II", 2) && !_fmemcmp(buf, "MM", 2)) {
  2026.         fclose(fp);
  2027.         return(BAD_HEAD);
  2028.     }
  2029.     if(_fmemcmp(buf, "II", 2) == 0) motint = TRUE;
  2030.     memset(palette, 0, 768);
  2031.     getw(fp);
  2032.     offset = GetMIlng(fp, motint);
  2033.     fseek(fp, offset, SEEK_SET);
  2034.     numtags = GetMIw(fp, motint);
  2035.  
  2036.     for(t = 0; t < numtags; ++t) {
  2037.         tag = GetMIw(fp, motint);
  2038.         type = GetMIw(fp, motint);
  2039.         if(type == 4) {
  2040.             length = GetMIlng(fp, motint);
  2041.             offset = GetMIlng(fp, motint);
  2042.         }
  2043.         else {
  2044.             if(motint) {
  2045.                 length = GetMIw(fp, motint);
  2046.                 GetMIw(fp, motint);
  2047.                 offset = GetMIw(fp, motint);
  2048.                 GetMIw(fp, motint);
  2049.             }
  2050.             else {
  2051.                 GetMIw(fp, motint);
  2052.                 length = GetMIw(fp, motint);
  2053.                 if(length > 2L) {
  2054.                     GetMIw(fp, motint);
  2055.                     offset = GetMIw(fp, motint);
  2056.                 }
  2057.                 else {
  2058.                     offset = GetMIw(fp, motint);
  2059.                     GetMIw(fp, motint);
  2060.                 }
  2061.             }
  2062.         }
  2063.  
  2064.         pos = ftell(fp);
  2065.         switch(tag) {
  2066.             case 256:
  2067.                 bmp.biWidth = offset;
  2068.                 break;
  2069.  
  2070.             case 257:
  2071.                 bmp.biHeight = offset;
  2072.                 break;
  2073.  
  2074.             case 258:
  2075.                 if(length > 1L) {
  2076.                     pos = ftell(fp);
  2077.                     fseek(fp, offset, SEEK_SET);
  2078.                     bitspersample = GetMIw(fp, motint);
  2079.                     fseek(fp, pos, SEEK_SET);
  2080.                 } else bitspersample = offset;
  2081.                 break;
  2082.  
  2083.             case 259:
  2084.                 compress = offset;
  2085.                 break;
  2086.  
  2087.             case 262:
  2088.                 photo = offset;
  2089.                 break;
  2090.  
  2091.             case 273:
  2092.                 if(type == 4) strtstrip = offset;
  2093.                 else strtstrip = offset & 0xffffL;
  2094.                 numstrips = length;
  2095.                 break;
  2096.  
  2097.             case 277:
  2098.                 bitsamples = offset;
  2099.                 break;
  2100.  
  2101.             case 278:
  2102.                 rows = offset;
  2103.                 break;
  2104.  
  2105.             case 320:
  2106.                 pos = ftell(fp);
  2107.                 colormap = TRUE;
  2108.                 fseek(fp, offset, SEEK_SET);
  2109.                 for(i = 0; i < (1 << bitspersample); ++i) {
  2110.                     if(i >= 256) break;
  2111.                     c = GetMIw(fp, motint);
  2112.                     if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
  2113.                     palette[i * 3] = c;
  2114.                 }
  2115.                 for(i = 0; i < (1 << bitspersample); ++i) {
  2116.                     if(i >= 256) break;
  2117.                     c = GetMIw(fp, motint);
  2118.                     if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
  2119.                     palette[i * 3 + 1] = c;
  2120.                 }
  2121.                 for(i = 0; i < (1 << bitspersample); ++i) {
  2122.                     if(i >= 256) break;
  2123.                     c = GetMIw(fp, motint);
  2124.                     if((c & 0xff00) && !(c & 0x00ff)) c = c>> 8;
  2125.                     palette[i * 3 + 2] = c;
  2126.                 }
  2127.                 fseek(fp, pos, SEEK_SET);
  2128.                 break;
  2129.         }
  2130.     }
  2131.  
  2132.  
  2133.     bmp.biBitCount = picbits = bitspersample * bitsamples;
  2134.     bytes = (bmp.biWidth * bmp.biBitCount + 7) >> 3;
  2135.     linewidth = SetLine();
  2136.  
  2137.     if(colormap != TRUE) {
  2138.         if(bmp.biBitCount == 1) {
  2139.             if(photo != 1)
  2140.                 memcpy(palette, "\377\377\377\000\000\000", 6);
  2141.             else
  2142.                 memcpy(palette, "\000\000\000\377\377\377", 6);
  2143.         }
  2144.         else {
  2145.             n = 255 / ((1 << bmp.biBitCount) - 1);
  2146.             for(i = 0; i < (1 << bmp.biBitCount); ++i)
  2147.                   memset(palette + i * 3, i * n, 3);
  2148.         }
  2149.     }
  2150.  
  2151.     if((line = malloc(max(bytes, linewidth))) == NULL) {
  2152.         fclose(fp);
  2153.         return(MEM_ERR);
  2154.     }
  2155.     bufsize = bmp.biHeight * linewidth;
  2156.     ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
  2157.     if((gptr = GlobalLock(ghnd)) == NULL) {
  2158.         free(line);
  2159.         fclose(fp);
  2160.         return(MEM_ERR);
  2161.     }
  2162.  
  2163.     if(rows == 0) rows = bmp.biHeight;
  2164.     for(j = 0; j < numstrips; ++j) {
  2165.         fseek(fp, strtstrip + (j * 4), SEEK_SET);
  2166.         if(numstrips > 1) fseek(fp, GetMIlng(fp, motint), SEEK_SET);
  2167.  
  2168.         for(k = 0; k < rows; ++k) {
  2169.             ++row;
  2170.             if(compress == 1)
  2171.                 fread(line, 1, bytes, fp);
  2172.  
  2173.             if(compress == 0x8005) {
  2174.                 n = 0;
  2175.                 do {
  2176.                     c = fgetc(fp);
  2177.                     if(c & 0x80) {
  2178.                         if(c != 0x80) {
  2179.                             i = ((~c) & 0xff) + 2;
  2180.                             c = fgetc(fp);
  2181.                             while((i--) && (n < bytes)) line[n++] = c;
  2182.                         }
  2183.                     }
  2184.                     else {
  2185.                         i = (c & 0xff) + 1;
  2186.                         while((i--) && (n < bytes)) line[n++] = fgetc(fp);
  2187.                     }
  2188.                 } while(n < bytes);
  2189.             }
  2190.             if(row > bmp.biHeight) continue;
  2191.             if(compress == 1 || compress == 0x8005) {
  2192.                 if(bmp.biBitCount == 24)
  2193.                     for(i = 0; i < bytes - 3; i += 3) {
  2194.                         c = line[i];
  2195.                         line[i] = line[i + 2];
  2196.                         line[i + 2] = c;
  2197.                     }
  2198.  
  2199.                 if(_fmemcpy(gptr + (bmp.biHeight - row) * linewidth, line, bytes) == NULL) {
  2200.                     GlobalUnlock(ghnd);
  2201.                     GlobalFree(ghnd);
  2202.                     free(line);
  2203.                     fclose(fp);
  2204.                     return(BAD_COPY);
  2205.                 }
  2206.             }
  2207.         }
  2208.     }
  2209.  
  2210.     free(line);
  2211.     fclose(fp);
  2212.     return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  2213. }
  2214.  
  2215.  
  2216. HBITMAP FAR PASCAL ReadWPG(LPSTR fname, HDC pichdc, HWND pichwnd, WORD dither,
  2217.                            WORD print, WORD x, WORD y, WORD scale) {
  2218.  
  2219.     FILE          *fp;
  2220.     int           c, d, i, j, n, type;
  2221.     unsigned int  r;
  2222.     int           repeat = 0;
  2223.     char          *line;
  2224.     long          bufsize;
  2225.     char huge     *gptr;
  2226.     int           bytes;
  2227.     unsigned long fc, l, t, offset;
  2228.  
  2229.     lstrcpy(path, fname);
  2230.     if((fp = fopen(path, "rb")) == NULL) return(NO_OPEN);
  2231.     if((fread((char *)&wpg, 1, sizeof(WPGHEAD), fp) != sizeof(WPGHEAD))  ||
  2232.         (memcmp(wpg.id, "\377WPC", 4))) {
  2233.         fclose(fp);
  2234.         return(BAD_HEAD);
  2235.     }
  2236.  
  2237.     bmp.biHeight = bmp.biWidth = 0;
  2238.     fseek(fp, wpg.start, SEEK_SET);
  2239.     memset(palette, 0, 768);
  2240.     memcpy(palette,"\000\000\000\377\377\377",6);
  2241.     do {
  2242.         type = fgetc(fp);
  2243.         t = ftell(fp);
  2244.         r = fgetc(fp);
  2245.         if(r == 0xff) {
  2246.             r = getw(fp);
  2247.             if(r & 0x8000) {
  2248.                 l = (unsigned long)(r & 0x7fff) << 16;
  2249.                 r = getw(fp);
  2250.                 l += (((unsigned long)r) + 4L);
  2251.             } else l = (((unsigned int)r) + 2L);
  2252.         } else l = (unsigned long)r;
  2253.  
  2254.         switch(type) {
  2255.             case 11:
  2256.                 bmp.biWidth = getw(fp);
  2257.                 bmp.biHeight = getw(fp);
  2258.                 bmp.biBitCount = picbits = getw(fp);
  2259.                 getw(fp);
  2260.                 getw(fp);
  2261.                 offset = ftell(fp);
  2262.                 if(bmp.biBitCount == 1) bytes = pixels2bytes(bmp.biWidth);
  2263.                 else if(bmp.biBitCount > 1 && bmp.biBitCount <= 4) {
  2264.                     j = bmp.biWidth;
  2265.                     if(j & 0x001)  ++i;
  2266.                     bytes = (j * 4) >> 3;
  2267.                 }
  2268.                 else bytes = bmp.biWidth;
  2269.                 linewidth = SetLine();
  2270.  
  2271.                 break;
  2272.  
  2273.             case 14:
  2274.                 fc = getw(fp);
  2275.                 j = getw(fp);
  2276.                 for(i = 0; i < j; ++i) {
  2277.                     if((fc + i * 3) >= 768) break;
  2278.                     palette[(fc + i) * 3] = fgetc(fp);
  2279.                     palette[((fc + i) * 3) + 1] = fgetc(fp);
  2280.                     palette[((fc + i) * 3) + 2] = fgetc(fp);
  2281.                 }
  2282.                 break;
  2283.  
  2284.               case 16:
  2285.                   if(bmp.biWidth = 0 || bmp.biHeight == 0) {
  2286.                       fclose(fp);
  2287.                     return (NO_BMP);
  2288.                 }
  2289.                 fseek(fp, offset, SEEK_SET);
  2290.                 if((line = malloc(max(bytes, (short)bmp.biWidth))) == NULL) {
  2291.                     fclose(fp);
  2292.                     return (MEM_ERR);
  2293.                 }
  2294.                 bufsize = bmp.biHeight * linewidth;
  2295.                 ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize);
  2296.                 if((gptr = GlobalLock(ghnd)) == NULL) {
  2297.                     free(line);
  2298.                     fclose(fp);
  2299.                     return(MEM_ERR);
  2300.                 }
  2301.  
  2302.                 for (j = 0; j < bmp.biHeight; ++j) {
  2303.                     n = 0;
  2304.                     if(repeat) --repeat;
  2305.                     else {
  2306.                         do {
  2307.                             c = fgetc(fp);
  2308.                             if((c & 0x0080) && (c & 0x007f)) {
  2309.                                 d = fgetc(fp);
  2310.                                 for(i = 0; i < (c & 0x7f); ++i) line[n++] = d;
  2311.                             }
  2312.                             else if((c & 0x0080) && !(c & 0x007f)) {
  2313.                                 d = fgetc(fp);
  2314.                                 for(i = 0; i < d; ++i) line[n++] = 0xff;
  2315.                             }
  2316.                             else if(!(c & 0x0080) && (c & 0x007f)) {
  2317.                                 for(i = 0; i < (c & 0x7f); ++i) line[n++] = fgetc(fp);
  2318.                             }
  2319.                             else {
  2320.                                 repeat = fgetc(fp);
  2321.                                 n = bytes;
  2322.                             }
  2323.                         } while(n < bytes);
  2324.                     }
  2325.                     if(_fmemcpy(gptr + (bmp.biHeight - j - 1) * linewidth, line, bytes) == NULL) {
  2326.                         GlobalUnlock(ghnd);
  2327.                         GlobalFree(ghnd);
  2328.                         free(line);
  2329.                         fclose(fp);
  2330.                         return(BAD_COPY);
  2331.                     }
  2332.                 }
  2333.  
  2334.                 free(line);
  2335.                 fclose(fp);
  2336.                 return(Display(gptr, pichdc, pichwnd, dither, print, x, y, scale));
  2337.         }
  2338.         fseek(fp, t + l + 1, SEEK_SET);
  2339.     } while(r != 16 && r != EOF);
  2340.     return(NO_BMP);
  2341. }
  2342.  
  2343.  
  2344. int SetLine() {
  2345.  
  2346.     int j, width;
  2347.  
  2348.     bmp.biSize = 40;
  2349.     bmp.biPlanes = 1;
  2350.     bmp.biCompression = 0;
  2351.     bmp.biSizeImage = 0;
  2352.     bmp.biXPelsPerMeter = 0;
  2353.     bmp.biYPelsPerMeter = 0;
  2354.     bmp.biClrUsed = 0;
  2355.     bmp.biClrImportant = 0;
  2356.     for(j = 0; j < 256; ++j) {
  2357.         bmpi.bmiColors[j].rgbRed = 0;
  2358.         bmpi.bmiColors[j].rgbGreen = 0;
  2359.         bmpi.bmiColors[j].rgbBlue = 0;
  2360.         bmpi.bmiColors[j].rgbReserved = 0;
  2361.     }
  2362.     if(bmp.biBitCount == 1)
  2363.         width = pixels2bytes(bmp.biWidth);
  2364.     if(bmp.biBitCount > 1 && bmp.biBitCount <= 4) {
  2365.         width = pixels2bytes(bmp.biWidth) << 2;
  2366.         bmp.biBitCount = 4;
  2367.     }
  2368.     if(bmp.biBitCount > 4 && bmp.biBitCount <= 8) {
  2369.         width = bmp.biWidth;
  2370.         bmp.biBitCount = 8;
  2371.     }
  2372.     if(bmp.biBitCount > 8) {
  2373.         width = bmp.biWidth * 3;
  2374.         bmp.biBitCount = 24;
  2375.     }
  2376.  
  2377.     if(width & 0x003) width = (width | 3) + 1;
  2378.  
  2379.     bmpi.bmiHeader = bmp;
  2380.     return(width);
  2381. }
  2382.  
  2383.  
  2384. int Display(unsigned char huge  *gptr, HDC pichdc, HWND pichwnd, int dither,
  2385.             int print, int x, int y, int scale) {
  2386.  
  2387.     int        bits, j, r;
  2388.     HDC        tempdc;
  2389.     HANDLE     hdcprev, chndl;
  2390.     HBITMAP    bhnd;
  2391.        LOGPALETTE *plogpal;
  2392.     HANDLE     hpal = NULL, chpal = NULL;
  2393.     HDC        oldpal;
  2394.  
  2395.     bits = (GetDeviceCaps(pichdc, PLANES) * GetDeviceCaps(pichdc, BITSPIXEL));
  2396.     if(bits >= 16) bits = 24;
  2397.  
  2398.     if(bmp.biBitCount > 8 && bits <= 8) {
  2399.         j = (1 << bits);
  2400.         if(Quantize(gptr, &j, palette) != 0) return(NO_PAL);
  2401.     }
  2402.  
  2403.        if(dither != 0 && picbits != 1) {
  2404.         if(dither == 1 || picbits > bits) {
  2405.             r = DitherPicture(gptr);
  2406.             GlobalUnlock(ghnd);
  2407.             GlobalFree(ghnd);
  2408.             if(r != 0) return(r);
  2409.             ghnd = dh;
  2410.             gptr = GlobalLock(ghnd);
  2411.         }
  2412.     }
  2413.     if(bmp.biBitCount <= 8 || bits <= 8) {
  2414.         if(bmp.biBitCount <= 8) j = 1 << bmp.biBitCount;
  2415.         if((plogpal = (LOGPALETTE *)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + (j * sizeof(PALETTEENTRY)))) != NULL) {
  2416.             plogpal->palVersion = 0x300;
  2417.             plogpal->palNumEntries = j;
  2418.             for(j = 0; j < plogpal->palNumEntries; ++j) {
  2419.                 plogpal->palPalEntry[j].peRed = bmpi.bmiColors[j].rgbRed = palette[j * 3];
  2420.                 plogpal->palPalEntry[j].peGreen = bmpi.bmiColors[j].rgbGreen = palette[j * 3 + 1];
  2421.                 plogpal->palPalEntry[j].peBlue = bmpi.bmiColors[j].rgbBlue = palette[j * 3 + 2];
  2422.                 plogpal->palPalEntry[j].peFlags = bmpi.bmiColors[j].rgbReserved = 0;
  2423.             }
  2424.             if((hpal = CreatePalette(plogpal)) == NULL) {
  2425.                 LocalFree((HANDLE)plogpal);
  2426.                 GlobalUnlock(ghnd);
  2427.                 GlobalFree(ghnd);
  2428.                 return(NO_PAL);
  2429.             }
  2430.  
  2431.             OpenClipboard(pichwnd);
  2432.             SetClipboardData(CF_PALETTE, CreatePalette(plogpal));
  2433.             CloseClipboard();
  2434.  
  2435.             LocalFree((HANDLE)plogpal);
  2436.             if((oldpal = SelectPalette(pichdc, hpal, 0)) == NULL) {
  2437.                 GlobalUnlock(ghnd);
  2438.                 GlobalFree(ghnd);
  2439.                 return(NO_PAL);
  2440.             }
  2441.             RealizePalette(pichdc);
  2442.         }
  2443.         else {
  2444.             GlobalUnlock(ghnd);
  2445.             GlobalFree(ghnd);
  2446.             return(MEM_ERR);
  2447.         }
  2448.     }
  2449.     if(print) {
  2450.  
  2451.         StretchDIBits(pichdc, x, y,
  2452.                       (short)bmp.biWidth * scale,
  2453.                        (short)bmp.biHeight * scale,
  2454.                        0, 0,
  2455.                        (short)bmp.biWidth, (short)bmp.biHeight,
  2456.                       gptr, (LPBITMAPINFO)&bmpi,
  2457.                       DIB_RGB_COLORS, SRCCOPY);
  2458.         bhnd = NULL;
  2459.  
  2460.     }
  2461.     else {
  2462.         if(pichwnd != 0) MoveWindow(pichwnd, 0, 0, (short)bmp.biWidth, (short)bmp.biHeight, TRUE);
  2463.         if((bhnd = CreateDIBitmap(pichdc, (LPBITMAPINFOHEADER)&bmp,
  2464.                                   CBM_INIT, gptr, (LPBITMAPINFO)&bmpi,
  2465.                                   DIB_RGB_COLORS)) == NULL) bhnd = NO_BHND;
  2466.     }
  2467.     if(hpal != NULL) {
  2468.           SelectPalette(pichdc, oldpal, 0);
  2469.            DeleteObject(hpal);
  2470.     }
  2471.  
  2472.     GlobalUnlock(ghnd);
  2473.     GlobalFree(ghnd);
  2474.     return(bhnd);
  2475. }
  2476.  
  2477.  
  2478. int Quantize(unsigned char huge *gptr, int far *colorcount, char *outputcolormap) {
  2479.  
  2480.     char far      *p, far *linebuffer;
  2481.     unsigned int  i, j;
  2482.     int           index;
  2483.     int           newcolormapsize;
  2484.     int           numofentries;
  2485.     unsigned long mems;
  2486.     long          cred, cgreen, cblue;
  2487.     char huge     *lpstr;
  2488.     NEWCOLOR      far *newcolorsubdiv;
  2489.     QCOLOR        far *colorarrayentries, far *quantizedcolor;
  2490.     HANDLE        memh;
  2491.  
  2492.     mems = ((long)sizeof(QCOLOR) * 4096L) +
  2493.            ((long)sizeof(NEWCOLOR) * 256L) +
  2494.            ((long)linewidth) +
  2495.            ((long)sizeof(QCOLOR far *) * 4096L);
  2496.  
  2497.     if((memh = GlobalAlloc(GMEM_MOVEABLE, mems)) == NULL)
  2498.         return(MEM_ERR);
  2499.     if((lpstr = (char huge *)GlobalLock(memh)) == NULL) {
  2500.         GlobalFree(memh);
  2501.         return(MEM_ERR);
  2502.     }
  2503.  
  2504.     colorarrayentries = (QCOLOR far *)lpstr;
  2505.     newcolorsubdiv = (NEWCOLOR far *)(lpstr + (long)sizeof(QCOLOR) * 4096L);
  2506.     linebuffer = (char far *)(lpstr + (((long)sizeof(QCOLOR) * 4096L) +
  2507.                  ((long)sizeof(NEWCOLOR) * 256L)));
  2508.  
  2509.     for(i = 0; i < 4096; i++) {
  2510.         colorarrayentries[i].RGB[0] = i >> 8;
  2511.         colorarrayentries[i].RGB[1] = (i >> 4) & 0x0f;
  2512.         colorarrayentries[i].RGB[2] = i & 0x0f;
  2513.         colorarrayentries[i].count = 0L;
  2514.     }
  2515.  
  2516.     for(i = 0; i < bmp.biHeight; ++i) {
  2517.         if(_fmemcpy(linebuffer, gptr + (bmp.biHeight - i - 1) * linewidth, linewidth) == NULL) {
  2518.             GlobalUnlock(memh);
  2519.                GlobalFree(memh);
  2520.             return(BAD_COPY);
  2521.         }
  2522.         p = linebuffer;
  2523.         for(j = 0; j < bmp.biWidth; ++j) {
  2524.             index = ((p[2] & 0xf0) << 4) +
  2525.                      (p[1] & 0xf0) +
  2526.                     ((p[0] & 0xf0) >> 4);
  2527.  
  2528.             colorarrayentries[index].count++;
  2529.             p += 3;
  2530.         }
  2531.     }
  2532.  
  2533.     for(i = 0; i < 256; i++) {
  2534.         newcolorsubdiv[i].quantizedcolors = (QCOLOR far *)NULL;
  2535.         newcolorsubdiv[i].count = 0L;
  2536.         newcolorsubdiv[i].numentries = 0L;
  2537.         for(j = 0; j < 3; ++j) {
  2538.             newcolorsubdiv[i].RGBmin[j] = 0;
  2539.             newcolorsubdiv[i].RGBwidth[j] = 255;
  2540.         }
  2541.     }
  2542.     for(i = 0; i < 4096; i++)
  2543.         if(colorarrayentries[i].count > 0) break;
  2544.     quantizedcolor = newcolorsubdiv[0].quantizedcolors = &colorarrayentries[i];
  2545.     numofentries = 1;
  2546.  
  2547.     while(++i < 4096)
  2548.         if(colorarrayentries[i].count > 0) {
  2549.             quantizedcolor->pnext = &colorarrayentries[i];
  2550.             quantizedcolor = &colorarrayentries[i];
  2551.             numofentries++;
  2552.         }
  2553.  
  2554.     quantizedcolor->pnext = (QCOLOR far *)NULL;
  2555.     newcolorsubdiv[0].numentries = numofentries;
  2556.     newcolorsubdiv[0].count = (long)bmp.biWidth * (long)bmp.biHeight;
  2557.     newcolormapsize = 1;
  2558.  
  2559.     lpstr += ((long)sizeof(QCOLOR) * 4096L) +
  2560.              ((long)sizeof(NEWCOLOR) * 256L) +
  2561.              ((long)linewidth);
  2562.  
  2563.     DivideMap(newcolorsubdiv, *colorcount, &newcolormapsize, lpstr);
  2564.  
  2565.     if(newcolormapsize < *colorcount) {
  2566.         for(i = newcolormapsize; i < *colorcount; i++)
  2567.             outputcolormap[i * 3] =
  2568.             outputcolormap[i * 3 + 1] =
  2569.             outputcolormap[i * 3 + 2] = 0;
  2570.     }
  2571.     for(i = 0; i < newcolormapsize; i++) {
  2572.         if((j = newcolorsubdiv[i].numentries) > 0) {
  2573.             quantizedcolor = newcolorsubdiv[i].quantizedcolors;
  2574.             cred = cgreen = cblue = 0;
  2575.             while(quantizedcolor) {
  2576.                 quantizedcolor->newcolorindex = i;
  2577.                 cred += quantizedcolor->RGB[0];
  2578.                 cgreen += quantizedcolor->RGB[1];
  2579.                 cblue += quantizedcolor->RGB[2];\
  2580.                 quantizedcolor = quantizedcolor->pnext;
  2581.             }
  2582.             outputcolormap[i * 3] = (int)(cred << 4) / j;
  2583.             outputcolormap[i * 3 + 1] = (int)(cgreen << 4) / j;
  2584.             outputcolormap[i * 3 + 2] = (int)(cblue << 4) / j;
  2585.         }
  2586.     }
  2587.  
  2588.     GlobalUnlock(memh);
  2589.     GlobalFree(memh);
  2590.     *colorcount = newcolormapsize;
  2591.     return(0);
  2592. }
  2593.  
  2594.  
  2595. int DivideMap(NEWCOLOR far *newcolorsubdiv, int colormapsize,
  2596.               int far *newcolormapsize, char huge *lpstr) {
  2597.  
  2598.     unsigned int  i, j;
  2599.     int           maxsize, index = 0;
  2600.     unsigned int  numentries, mincolor, maxcolor;
  2601.     long          sum, count;
  2602.     QCOLOR far    *quantizedcolor, far * far *sortarray;
  2603.  
  2604.     while(colormapsize > *newcolormapsize) {
  2605.         maxsize = -1;
  2606.         for(i = 0; i < *newcolormapsize; i++) {
  2607.             for(j = 0; j < 3; j++) {
  2608.                 if(((int)newcolorsubdiv[i].RGBwidth[j]) > maxsize && newcolorsubdiv[i].numentries > 1) {
  2609.                     maxsize = newcolorsubdiv[i].RGBwidth[j];
  2610.                     index = i;
  2611.                     sortRGBaxis = j;
  2612.                 }
  2613.             }
  2614.         }
  2615.         if(maxsize == -1) return(1);
  2616.  
  2617.         sortarray = (QCOLOR far * far *)lpstr;
  2618.  
  2619.         for(j = 0, quantizedcolor = newcolorsubdiv[index].quantizedcolors;
  2620.             j < newcolorsubdiv[index].numentries && quantizedcolor != (QCOLOR far *)NULL;
  2621.             j++, quantizedcolor = quantizedcolor->pnext)
  2622.                 sortarray[j] = quantizedcolor;
  2623.  
  2624.         psort((char far * far *)sortarray, newcolorsubdiv[index].numentries);
  2625.  
  2626.         for(j = 0; j < newcolorsubdiv[index].numentries - 1; j++)
  2627.             sortarray[j]->pnext = sortarray[j + 1];
  2628.         sortarray[newcolorsubdiv[index].numentries - 1]->pnext = (QCOLOR far *)NULL;
  2629.         newcolorsubdiv[index].quantizedcolors = quantizedcolor = sortarray[0];
  2630.  
  2631.         sum = newcolorsubdiv[index].count / 2 - quantizedcolor->count;
  2632.         numentries = 1;
  2633.         count = quantizedcolor->count;
  2634.         while((sum -= quantizedcolor->pnext->count) >= 0 &&
  2635.                quantizedcolor->pnext != (QCOLOR far *)NULL &&
  2636.                quantizedcolor->pnext->pnext != (QCOLOR far *)NULL) {
  2637.                   quantizedcolor = quantizedcolor->pnext;
  2638.                   numentries++;
  2639.                   count += quantizedcolor->count;
  2640.         }
  2641.         maxcolor = quantizedcolor->RGB[sortRGBaxis];
  2642.         mincolor = quantizedcolor->pnext->RGB[sortRGBaxis];
  2643.         maxcolor <<= 4;
  2644.         mincolor <<= 4;
  2645.  
  2646.         newcolorsubdiv[*newcolormapsize].quantizedcolors = quantizedcolor->pnext;
  2647.         quantizedcolor->pnext = (QCOLOR far *)NULL;
  2648.         newcolorsubdiv[*newcolormapsize].count = count;
  2649.         newcolorsubdiv[index].count -= count;
  2650.         newcolorsubdiv[*newcolormapsize].numentries = newcolorsubdiv[index].numentries - numentries;
  2651.         newcolorsubdiv[index].numentries = numentries;
  2652.  
  2653.         for(j = 0; j < 3; j++) {
  2654.             newcolorsubdiv[*newcolormapsize].RGBmin[j] = newcolorsubdiv[index].RGBmin[j];
  2655.             newcolorsubdiv[*newcolormapsize].RGBwidth[j] = newcolorsubdiv[index].RGBwidth[j];
  2656.         }
  2657.         newcolorsubdiv[*newcolormapsize].RGBwidth[sortRGBaxis] =
  2658.             newcolorsubdiv[*newcolormapsize].RGBmin[sortRGBaxis] +
  2659.             newcolorsubdiv[*newcolormapsize].RGBwidth[sortRGBaxis] -
  2660.             mincolor;
  2661.         newcolorsubdiv[*newcolormapsize].RGBmin[sortRGBaxis] = mincolor;
  2662.  
  2663.         newcolorsubdiv[index].RGBwidth[sortRGBaxis] =
  2664.             maxcolor - newcolorsubdiv[index].RGBmin[sortRGBaxis];
  2665.  
  2666.         (*newcolormapsize)++;
  2667.     }
  2668.     return(1);
  2669. }
  2670.  
  2671.  
  2672. void psort(char far * far *array, int number) {
  2673.  
  2674.     QCOLOR far *q1, far *q2;
  2675.     int        i, j, n, nr;
  2676.     char far   *temp, far *part;
  2677.  
  2678.     if(number < 8) {
  2679.         pinsert(array, number);
  2680.         return;
  2681.     }
  2682.     part = array[number / 2];
  2683.     i = -1;
  2684.     j = number;
  2685.     for(;;) {
  2686.         do {
  2687.             ++i;
  2688.             q1 = (QCOLOR far *)array[i];
  2689.             q2 = (QCOLOR far *)part;
  2690.             n = q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis];
  2691.         } while(n < 0);
  2692.  
  2693.         do {
  2694.             --j;
  2695.             q1 = (QCOLOR far *)array[j];
  2696.             q2 = (QCOLOR far *)part;
  2697.             n = q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis];
  2698.         } while(n > 0);
  2699.  
  2700.         if(i >= j) break;
  2701.  
  2702.         temp = array[i];
  2703.         array[i] = array[j];
  2704.         array[j] = temp;
  2705.     }
  2706.  
  2707.     nr = number - i;
  2708.     if(i < (number / 2)) {
  2709.         psort(array, i);
  2710.         psort(&array[i], nr);
  2711.     }
  2712.     else {
  2713.         psort(&array[i], nr);
  2714.         psort(array, i);
  2715.     }
  2716. }
  2717.  
  2718.  
  2719. void pinsert(char far * far *array, int number) {
  2720.  
  2721.     QCOLOR far *q1, far *q2;
  2722.     char far   *temp, far *part;
  2723.     int        i, j;
  2724.  
  2725.     for(i = 1; i < number; ++i) {
  2726.         temp = array[i];
  2727.         j = i - 1;
  2728.         while(j >= 0) {
  2729.             q1 = (QCOLOR far*)temp;
  2730.             q2 = (QCOLOR far*)array[j];
  2731.             if(q1->RGB[sortRGBaxis] - q2->RGB[sortRGBaxis] > 0) break;
  2732.             array[j + 1] = array[j];
  2733.             --j;
  2734.         }
  2735.         array[j + 1] = temp;
  2736.     }
  2737. }
  2738.  
  2739.  
  2740. int DitherPicture(unsigned char huge *gptr) {
  2741.  
  2742.     static char fixedpalette[] = {
  2743.                       0,   0,   0,
  2744.                     255,   0,   0,
  2745.                       0, 255,   0,
  2746.                     255, 255,   0,
  2747.                       0,   0, 255,
  2748.                     255,   0, 255,
  2749.                       0, 255, 255,
  2750.                     255, 255, 255};
  2751.  
  2752.     static char bayerpattern[8][8] = {
  2753.         0, 32,  8, 40,  2, 34, 10, 42,
  2754.        48, 16, 56, 24, 50, 18, 58, 26,
  2755.        12, 44,  4, 36, 14, 46,  6, 38,
  2756.        60, 28, 52, 20, 62, 30, 54, 22,
  2757.         3, 35, 11, 43,  1, 33,  9, 41,
  2758.        51, 19, 59, 27, 49, 17, 57, 25,
  2759.        15, 47,  7, 39, 13, 45,  5, 37,
  2760.        63, 31, 55, 23, 61, 29, 53, 21};
  2761.  
  2762.     unsigned char huge *pd;
  2763.     unsigned char      *pr, *linebuffer;
  2764.     unsigned long      size;
  2765.     unsigned int       ditherlinewidth;
  2766.     unsigned int       a, i, j, n, x;
  2767.  
  2768.     ditherlinewidth = pixels2bytes(bmp.biWidth) << 2;
  2769.     if(ditherlinewidth & 0x003) ditherlinewidth = (ditherlinewidth | 3) + 1;
  2770.  
  2771.     size = (long)ditherlinewidth * (long)(bmp.biHeight + 1);
  2772.  
  2773.     if((dh = GlobalAlloc(GMEM_MOVEABLE, size)) == NULL) return(MEM_ERR);
  2774.     if((pd = GlobalLock(dh)) == NULL) {
  2775.         GlobalFree(dh);
  2776.         return(MEM_ERR);
  2777.     }
  2778.     if((linebuffer = (char *)malloc((short)bmp.biWidth * 3)) == NULL) {
  2779.         GlobalUnlock(dh);
  2780.         GlobalFree(dh);
  2781.         return(MEM_ERR);
  2782.     }
  2783.  
  2784.     for(i = 0; i < bmp.biHeight; ++i) {
  2785.         pr = linebuffer;
  2786.         if(bmp.biBitCount == 4) {
  2787.             for(j = x = 0; j < bmp.biWidth;) {
  2788.                 n = (gptr[(bmp.biHeight - i - 1) * linewidth + x] & 0x00f0) >> 4;
  2789.                 memcpy(pr, palette + n * 3, 3);
  2790.                 pr += 3;
  2791.                 ++j;
  2792.                 if(j < bmp.biWidth) {
  2793.                     n = gptr[(bmp.biHeight - i - 1) * linewidth + x] & 0x000f;
  2794.                     memcpy(pr, palette + n * 3, 3);
  2795.                     pr += 3;
  2796.                 }
  2797.                 ++j;
  2798.                 ++x;
  2799.             }
  2800.         }
  2801.         if(bmp.biBitCount == 8)
  2802.             for(j = 0; j < bmp.biWidth; ++j) {
  2803.                 n = gptr[(bmp.biHeight - i - 1) * linewidth + j] & 0xff;
  2804.                 memcpy(pr, palette + n * 3, 3);
  2805.                 pr += 3;
  2806.             }
  2807.  
  2808.         if(bmp.biBitCount == 24)
  2809.             for(j = 0; j < bmp.biWidth; ++j) {
  2810.                 pr[0] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3 + 2];
  2811.                 pr[1] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3 + 1];
  2812.                 pr[2] = gptr[(bmp.biHeight - i - 1) * linewidth + j * 3];
  2813.                 pr += 3;
  2814.             }
  2815.  
  2816.         pr = linebuffer;
  2817.  
  2818.         for(j = x = 0; j < bmp.biWidth;) {
  2819.             a = bayerpattern[i & 0x0007][j & 0x0007] << 2;
  2820.             n = 0;
  2821.             if(pr[0] > a) n |= 0x01;
  2822.             if(pr[1] > a) n |= 0x02;
  2823.             if(pr[2] > a) n |= 0x04;
  2824.             pr += 3;
  2825.             pd[(bmp.biHeight - i - 1) * ditherlinewidth + x] = ((n << 4) & 0x00f0);
  2826.             ++j;
  2827.             if(j < bmp.biWidth) {
  2828.                  a = bayerpattern[i & 0x0007][j & 0x0007] << 2;
  2829.                 n = 0;
  2830.                 if(pr[0] > a) n |= 0x01;
  2831.                 if(pr[1] > a) n |= 0x02;
  2832.                 if(pr[2] > a) n |= 0x04;
  2833.                 pr += 3;
  2834.                 pd[(bmp.biHeight - i - 1) * ditherlinewidth + x] |= (n & 0x000f);
  2835.             }
  2836.             ++j;
  2837.             ++x;
  2838.         }
  2839.     }
  2840.  
  2841.     free(linebuffer);
  2842.     linewidth = ditherlinewidth;
  2843.     bmp.biBitCount = picbits = 4;
  2844.     bmpi.bmiHeader = bmp;
  2845.     GlobalUnlock(dh);
  2846.     memcpy(palette, fixedpalette, 24);
  2847.     return(0);
  2848. }
  2849.  
  2850.  
  2851. long motr2intellng(long ml, int tf) {
  2852.     if(tf) return(ml);
  2853.     return(((ml & 0xff000000L) >> 24) +
  2854.            ((ml & 0x00ff0000L) >> 8) +
  2855.            ((ml & 0x0000ff00L) << 8) +
  2856.            ((ml & 0x000000ffL) << 24));
  2857. }
  2858. int motr2intelint(int ml, int tf) {
  2859.     if(tf) return(ml);
  2860.     return(((ml & 0xff00) >> 8) +
  2861.            ((ml & 0xff) << 8));
  2862. }
  2863.  
  2864.  
  2865. unsigned int GetMIw(FILE *fp, int tf)
  2866. {
  2867.     if(tf) return((fgetc(fp) & 0xff) + ((fgetc(fp) & 0xff) << 8));
  2868.     else return(((fgetc(fp) & 0xff) << 8) + (fgetc(fp) & 0xff));
  2869. }
  2870.  
  2871.  
  2872. unsigned long GetMIlng(FILE *fp, int tf)
  2873. {
  2874.     if(tf)
  2875.          return(((unsigned long)(fgetc(fp) & 0xff) << 24) +
  2876.           ((unsigned long)(fgetc(fp) & 0xff) << 16) +
  2877.           ((unsigned long)(fgetc(fp) & 0xff) << 8) +
  2878.           (unsigned long)(fgetc(fp) & 0xff));
  2879.     else
  2880.         return((unsigned long)(fgetc(fp) & 0xff) +
  2881.           ((unsigned long)(fgetc(fp) & 0xff) << 8) +
  2882.           ((unsigned long)(fgetc(fp) & 0xff) << 16) +
  2883.           ((unsigned long)(fgetc(fp) & 0xff) << 24));
  2884. }
  2885.